From 780c92968a67cb009997a2efbcb0d1c599e9fa0c Mon Sep 17 00:00:00 2001 From: Sean Story Date: Fri, 12 Dec 2025 15:30:15 -0600 Subject: [PATCH 01/49] First pass at a Sharepoint Online fetcher --- .github/CODEOWNERS | 1 + .../data-context-sources-connectors-list.md | 1 + .../sharepoint-online-action-type.md | 89 ++++++ docs/reference/toc.yml | 1 + .../kbn-connector-specs/src/all_specs.ts | 1 + .../src/connector_icons_map.ts | 10 + .../specs/sharepoint_online/icon/index.tsx | 17 ++ .../sharepoint_online/icon/sharepoint.svg | 1 + .../sharepoint_online.test.ts | 269 ++++++++++++++++++ .../sharepoint_online/sharepoint_online.ts | 122 ++++++++ 10 files changed, 512 insertions(+) create mode 100644 docs/reference/connectors-kibana/sharepoint-online-action-type.md create mode 100644 src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/index.tsx create mode 100644 src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/sharepoint.svg create mode 100644 src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.test.ts create mode 100644 src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 24016a5db2142..b78a1c51f07a5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2319,6 +2319,7 @@ src/platform/packages/shared/kbn-connector-specs/src/specs/notion/** @elastic/wo src/platform/packages/shared/kbn-connector-specs/src/specs/shodan/** @elastic/workflows-eng src/platform/packages/shared/kbn-connector-specs/src/specs/urlvoid/** @elastic/workflows-eng src/platform/packages/shared/kbn-connector-specs/src/specs/virustotal/** @elastic/workflows-eng +src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/** @elastic/workchat-eng # Gap fill feature has shared responsibility between response-ops and security-detection-engine /x-pack/platform/plugins/shared/alerting/common/routes/gaps @elastic/response-ops @elastic/security-detection-engine diff --git a/docs/reference/connectors-kibana/_snippets/data-context-sources-connectors-list.md b/docs/reference/connectors-kibana/_snippets/data-context-sources-connectors-list.md index 9fe6dd69a3ee7..d6fce733ef57d 100644 --- a/docs/reference/connectors-kibana/_snippets/data-context-sources-connectors-list.md +++ b/docs/reference/connectors-kibana/_snippets/data-context-sources-connectors-list.md @@ -5,6 +5,7 @@ * [AbuseIPDB](/reference/connectors-kibana/abuseipdb-action-type.md): Check IP reputation and report abusive IPs. * [AlienVault OTX](/reference/connectors-kibana/alienvault-otx-action-type.md): Retrieve community-driven threat intelligence. * [GreyNoise](/reference/connectors-kibana/greynoise-action-type.md): Detect and classify Internet scanning noise. +* [Sharepoint online](/reference/connectors-kibana/sharepoint-online-action-type.md): TODO: Add brief description. * [Shodan](/reference/connectors-kibana/shodan-action-type.md): Perform Internet-wide asset discovery and vulnerability scanning. * [URLVoid](/reference/connectors-kibana/urlvoid-action-type.md): Check domain and URL reputation using multi-engine scanning. * [VirusTotal](/reference/connectors-kibana/virustotal-action-type.md): Perform file scanning, URL analysis, and threat intelligence lookups. \ No newline at end of file diff --git a/docs/reference/connectors-kibana/sharepoint-online-action-type.md b/docs/reference/connectors-kibana/sharepoint-online-action-type.md new file mode 100644 index 0000000000000..c8dfca29d3301 --- /dev/null +++ b/docs/reference/connectors-kibana/sharepoint-online-action-type.md @@ -0,0 +1,89 @@ +--- +navigation_title: "SharePoint Online" +mapped_pages: + - https://www.elastic.co/guide/en/kibana/current/sharepoint-online-action-type.html +applies_to: + stack: preview + serverless: preview +--- + +# SharePoint Online connector [sharepoint-online-action-type] + +The SharePoint Online connector enables federated search capabilities across SharePoint sites, pages, and content using the Microsoft Graph API. + +## Create connectors in {{kib}} [define-sharepoint-online-ui] + +You can create connectors in **{{stack-manage-app}} > {{connectors-ui}}**. For example: + +### Connector configuration [sharepoint-online-connector-configuration] + +SharePoint Online connectors have the following configuration properties: + +Region +: The geographic region where your SharePoint tenant is hosted. Required for search operations. Valid values: + - `NAM` - North America + - `EUR` - Europe + - `APC` - Asia Pacific + - `LAM` - Latin America + - `MEA` - Middle East and Africa + +Token URL +: The OAuth 2.0 token endpoint URL. Use the format: `https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token` + +Client ID +: The application (client) ID from your Microsoft Entra app registration. + +Client Secret +: The client secret generated for your Microsoft Entra application. + + +## Test connectors [sharepoint-online-action-configuration] + +You can test connectors as you're creating or editing the connector in {{kib}}. The test verifies connectivity by accessing the root SharePoint site. + +The SharePoint Online connector has the following action: + +Search +: Search for content across SharePoint sites, lists, and drives using Microsoft Graph Search API. + - **query** (required): The search query string. + - **entityTypes** (optional): Array of entity types to search. Valid values: `site`, `list`, `listItem`, `drive`, `driveItem`. Defaults to `driveItem`. + - **from** (optional): Offset for pagination. + - **size** (optional): Number of results to return. + + +## Get API credentials [sharepoint-online-api-credentials] + +To use the SharePoint Online connector, you need to: + +1. Register an application in Microsoft Entra (Azure AD): + - Go to the [Azure Portal](https://portal.azure.com/) + - Navigate to **Microsoft Entra ID** > **App registrations** + - Click **New registration** + - Provide a name for your application + - Select **Accounts in this organizational directory only** + - Click **Register** + +2. Configure API permissions: + - In your app registration, go to **API permissions** + - Click **Add a permission** > **Microsoft Graph** > **Application permissions** + - Add the following permissions: + - `Sites.Read.All` - Read items in all site collections + - `Sites.ReadWrite.All` - Read and write items in all site collections (if write operations needed) + - Click **Grant admin consent** for your organization + +3. Create a client secret: + - In your app registration, go to **Certificates & secrets** + - Click **New client secret** + - Provide a description and select an expiration period + - Click **Add** + - Copy the secret value immediately (it won't be shown again) + +4. Gather the following information for the connector configuration: + - **Region**: Select the geographic region where your Microsoft 365 tenant is hosted: + - Check your SharePoint URL (e.g., `contoso.sharepoint.com` vs `contoso-my.sharepoint.eu`) + - Common mappings: `.com` domains typically use `NAM`, `.eu` domains use `EUR` + - If unsure, check your Microsoft 365 admin center under **Settings** > **Org settings** > **Organization profile** + - **Tenant ID**: Found in **Overview** section of your app registration (needed for Token URL) + - **Token URL**: Construct using the format `https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token` + - **Client ID**: Found in **Overview** section (also called Application ID) + - **Client Secret**: The value you copied in step 3 (this is the only sensitive field) diff --git a/docs/reference/toc.yml b/docs/reference/toc.yml index 8ed7d1d515e47..463ab23777f0f 100644 --- a/docs/reference/toc.yml +++ b/docs/reference/toc.yml @@ -75,6 +75,7 @@ toc: - file: connectors-kibana/alienvault-otx-action-type.md - file: connectors-kibana/greynoise-action-type.md - file: connectors-kibana/notion-action-type.md + - file: connectors-kibana/sharepoint-online-action-type.md - file: connectors-kibana/shodan-action-type.md - file: connectors-kibana/urlvoid-action-type.md - file: connectors-kibana/virustotal-action-type.md diff --git a/src/platform/packages/shared/kbn-connector-specs/src/all_specs.ts b/src/platform/packages/shared/kbn-connector-specs/src/all_specs.ts index f2b0a1e9f2689..874b15750523d 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/all_specs.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/all_specs.ts @@ -14,3 +14,4 @@ export * from './specs/notion/notion'; export * from './specs/shodan/shodan'; export * from './specs/urlvoid/urlvoid'; export * from './specs/virustotal/virustotal'; +export * from './specs/sharepoint_online/sharepoint_online'; diff --git a/src/platform/packages/shared/kbn-connector-specs/src/connector_icons_map.ts b/src/platform/packages/shared/kbn-connector-specs/src/connector_icons_map.ts index 8c0e8981ddd79..936652f86e1b0 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/connector_icons_map.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/connector_icons_map.ts @@ -34,4 +34,14 @@ export const ConnectorIconsMap: Map< ), ], ['.notion', lazy(() => import(/* webpackChunkName: "connectorNotion" */ './specs/notion/icon'))], + + [ + '.sharepointOnline', + lazy( + () => + import( + /* webpackChunkName: "connectorIconsharepointonline" */ './specs/sharepoint_online/icon' + ) + ), + ], ]); diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/index.tsx b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/index.tsx new file mode 100644 index 0000000000000..39a238c55ddb9 --- /dev/null +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/index.tsx @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import React from 'react'; +import { EuiIcon } from '@elastic/eui'; +import type { ConnectorIconProps } from '../../../types'; +import sharepointIcon from './sharepoint.svg'; + +export default (props: ConnectorIconProps) => { + return ; +}; diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/sharepoint.svg b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/sharepoint.svg new file mode 100644 index 0000000000000..f8b1afc5fbac6 --- /dev/null +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/sharepoint.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.test.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.test.ts new file mode 100644 index 0000000000000..6126c3c3d07fc --- /dev/null +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.test.ts @@ -0,0 +1,269 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import type { ActionContext } from '../../connector_spec'; +import { SharepointOnline } from './sharepoint_online'; + +describe('SharepointOnline', () => { + const mockClient = { + get: jest.fn(), + post: jest.fn(), + }; + + const mockContext = { + client: mockClient, + log: { debug: jest.fn(), error: jest.fn() }, + config: { region: 'NAM' }, + } as unknown as ActionContext; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('search action', () => { + it('should search with default entity types', async () => { + const mockResponse = { + data: { + value: [ + { + hitsContainers: [ + { + hits: [ + { + hitId: '1', + resource: { + '@odata.type': '#microsoft.graph.driveItem', + name: 'Document.docx', + }, + }, + ], + total: 1, + }, + ], + }, + ], + }, + }; + mockClient.post.mockResolvedValue(mockResponse); + + const result = await SharepointOnline.actions.search.handler(mockContext, { + query: 'test document', + }); + + expect(mockClient.post).toHaveBeenCalledWith( + 'https://graph.microsoft.com/v1.0/search/query', + { + requests: [ + { + entityTypes: ['driveItem'], + query: { + queryString: 'test document', + }, + region: 'NAM', + }, + ], + } + ); + expect(result).toEqual(mockResponse.data); + }); + + it('should search with custom entity types', async () => { + const mockResponse = { + data: { + value: [ + { + hitsContainers: [ + { + hits: [ + { + hitId: '1', + resource: { + '@odata.type': '#microsoft.graph.site', + displayName: 'Test Site', + }, + }, + ], + total: 1, + }, + ], + }, + ], + }, + }; + mockClient.post.mockResolvedValue(mockResponse); + + await SharepointOnline.actions.search.handler(mockContext, { + query: 'project site', + entityTypes: ['site', 'list'], + }); + + expect(mockClient.post).toHaveBeenCalledWith( + 'https://graph.microsoft.com/v1.0/search/query', + { + requests: [ + { + entityTypes: ['site', 'list'], + query: { + queryString: 'project site', + }, + region: 'NAM', + }, + ], + } + ); + }); + + it('should include pagination parameters', async () => { + const mockResponse = { + data: { + value: [ + { + hitsContainers: [ + { + hits: [], + total: 100, + moreResultsAvailable: true, + }, + ], + }, + ], + }, + }; + mockClient.post.mockResolvedValue(mockResponse); + + await SharepointOnline.actions.search.handler(mockContext, { + query: 'documents', + from: 10, + size: 25, + }); + + expect(mockClient.post).toHaveBeenCalledWith( + 'https://graph.microsoft.com/v1.0/search/query', + { + requests: [ + { + entityTypes: ['driveItem'], + query: { + queryString: 'documents', + }, + region: 'NAM', + from: 10, + size: 25, + }, + ], + } + ); + }); + + it('should handle empty search results', async () => { + const mockResponse = { + data: { + value: [ + { + hitsContainers: [ + { + hits: [], + total: 0, + }, + ], + }, + ], + }, + }; + mockClient.post.mockResolvedValue(mockResponse); + + const result = await SharepointOnline.actions.search.handler(mockContext, { + query: 'nonexistent', + }); + + expect(result).toEqual(mockResponse.data); + }); + }); + + describe('test handler', () => { + it('should return success when API is accessible', async () => { + const mockResponse = { + data: { + id: 'root', + displayName: 'Contoso', + name: 'contoso', + webUrl: 'https://contoso.sharepoint.com', + }, + }; + mockClient.get.mockResolvedValue(mockResponse); + + if (!SharepointOnline.test) { + throw new Error('Test handler not defined'); + } + const result = await SharepointOnline.test.handler(mockContext); + + expect(mockClient.get).toHaveBeenCalledWith('https://graph.microsoft.com/v1.0/sites/root'); + expect(result).toEqual({ + ok: true, + message: 'Successfully connected to SharePoint Online: Contoso', + }); + }); + + it('should handle site without display name', async () => { + const mockResponse = { + data: { + id: 'root', + name: 'root', + }, + }; + mockClient.get.mockResolvedValue(mockResponse); + + if (!SharepointOnline.test) { + throw new Error('Test handler not defined'); + } + const result = await SharepointOnline.test.handler(mockContext); + + expect(result).toEqual({ + ok: true, + message: 'Successfully connected to SharePoint Online: Unknown', + }); + }); + + it('should return failure when API is not accessible', async () => { + mockClient.get.mockRejectedValue(new Error('Invalid credentials')); + + if (!SharepointOnline.test) { + throw new Error('Test handler not defined'); + } + const result = await SharepointOnline.test.handler(mockContext); + + expect(result.ok).toBe(false); + expect(result.message).toBe('Invalid credentials'); + }); + + it('should handle network errors', async () => { + mockClient.get.mockRejectedValue(new Error('Network timeout')); + + if (!SharepointOnline.test) { + throw new Error('Test handler not defined'); + } + const result = await SharepointOnline.test.handler(mockContext); + + expect(result.ok).toBe(false); + expect(result.message).toBe('Network timeout'); + }); + + it('should handle authentication errors', async () => { + mockClient.get.mockRejectedValue(new Error('401 Unauthorized')); + + if (!SharepointOnline.test) { + throw new Error('Test handler not defined'); + } + const result = await SharepointOnline.test.handler(mockContext); + + expect(result.ok).toBe(false); + expect(result.message).toBe('401 Unauthorized'); + }); + }); +}); diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts new file mode 100644 index 0000000000000..bee9a5bdef995 --- /dev/null +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { i18n } from '@kbn/i18n'; +import { z } from '@kbn/zod/v4'; +import type { ConnectorSpec } from '../../connector_spec'; + +export const SharepointOnline: ConnectorSpec = { + metadata: { + id: '.sharepointOnline', + displayName: 'SharePoint Online', + description: i18n.translate('core.kibanaConnectorSpecs.sharepointOnline.metadata.description', { + defaultMessage: 'Search and explore SharePoint sites, pages, and content', + }), + minimumLicense: 'enterprise', + supportedFeatureIds: ['workflows'], + }, + + auth: { + types: [ + { + type: 'oauth_client_credentials', + defaults: { + scope: 'https://graph.microsoft.com/.default', + tokenUrl: 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token', + }, + }, + ], + }, + + schema: z.object({ + region: z + .enum(['NAM', 'EUR', 'APC', 'LAM', 'MEA']) + .meta({ label: 'Region' }) + .describe( + 'Geographic region for search queries (NAM=North America, EUR=Europe, APC=Asia Pacific, LAM=Latin America, MEA=Middle East/Africa)' + ), + }), + + actions: { + // https://learn.microsoft.com/en-us/graph/api/search-query + search: { + isTool: true, + input: z.object({ + query: z.string().describe('Search query'), + entityTypes: z + .array(z.enum(['site', 'list', 'listItem', 'drive', 'driveItem'])) + .optional() + .describe('Entity types to search'), + from: z.number().optional().describe('Offset for pagination'), + size: z.number().optional().describe('Number of results to return'), + }), + handler: async (ctx, input) => { + const typedInput = input as { + query: string; + entityTypes?: Array<'site' | 'list' | 'listItem' | 'drive' | 'driveItem'>; + from?: number; + size?: number; + }; + + const config = ctx.config as { region: string }; + + const searchRequest = { + requests: [ + { + entityTypes: typedInput.entityTypes ?? ['driveItem'], + query: { + queryString: typedInput.query, + }, + region: config.region, + ...(typedInput.from !== undefined && { from: typedInput.from }), + ...(typedInput.size !== undefined && { size: typedInput.size }), + }, + ], + }; + + try { + ctx.log.debug(`SharePoint search request: ${JSON.stringify(searchRequest, null, 2)}`); + const response = await ctx.client.post( + 'https://graph.microsoft.com/v1.0/search/query', + searchRequest + ); + return response.data; + } catch (error) { + ctx.log.error( + `SharePoint search failed: ${error.message}, Status: ${ + error.response?.status + }, Data: ${JSON.stringify(error.response?.data)}` + ); + throw error; + } + }, + }, + }, + + test: { + description: i18n.translate('core.kibanaConnectorSpecs.sharepointOnline.test.description', { + defaultMessage: 'Verifies SharePoint Online connection by checking API access', + }), + handler: async (ctx) => { + ctx.log.debug('SharePoint Online test handler'); + + try { + // Test connection by getting the root site + const response = await ctx.client.get('https://graph.microsoft.com/v1.0/sites/root'); + const siteName = response.data.displayName || 'Unknown'; + return { + ok: true, + message: `Successfully connected to SharePoint Online: ${siteName}`, + }; + } catch (error) { + return { ok: false, message: error.message }; + } + }, + }, +}; From 4691f1ed5c37bc7f344fcdaa8df4560aca7651d4 Mon Sep 17 00:00:00 2001 From: Sean Story Date: Mon, 15 Dec 2025 16:00:16 -0600 Subject: [PATCH 02/49] First pass at an OAuth Code Grant flow Replace console logging with loggers, add types Clarify how the auth impl works Correctly secure the callback endpoint Style success and failure pages Separate out concerns from the authorize route linting --- .../sharepoint-online-action-type.md | 168 ++++++-- .../kbn-connector-specs/src/all_auth_types.ts | 1 + .../auth_types/oauth_authorization_code.ts | 112 ++++++ .../src/auth_types/translations.ts | 14 + .../sharepoint_online/sharepoint_online.ts | 21 +- .../server/actions_client/actions_client.ts | 35 ++ .../actions/server/constants/saved_objects.ts | 1 + .../server/lib/connector_token_client.ts | 132 +++++++ .../actions/server/lib/get_axios_instance.ts | 47 +++ ...t_oauth_authorization_code_access_token.ts | 148 +++++++ .../shared/actions/server/lib/index.ts | 2 + .../server/lib/oauth_authorization_service.ts | 182 +++++++++ .../actions/server/lib/oauth_state_client.ts | 208 ++++++++++ .../request_oauth_authorization_code_token.ts | 50 +++ .../server/lib/request_oauth_refresh_token.ts | 47 +++ .../actions/server/lib/request_oauth_token.ts | 4 + .../generate_executor_function.ts | 8 +- .../plugins/shared/actions/server/plugin.ts | 6 + .../server/routes/get_oauth_access_token.ts | 28 +- .../shared/actions/server/routes/index.ts | 20 +- .../actions/server/routes/oauth_authorize.ts | 146 +++++++ .../actions/server/routes/oauth_callback.ts | 367 ++++++++++++++++++ .../actions/server/saved_objects/index.ts | 51 ++- .../actions/server/saved_objects/mappings.ts | 40 ++ .../saved_objects/model_versions/index.ts | 1 + .../oauth_state_model_versions.ts | 19 + .../schemas/raw_connector_token/v1.ts | 2 + .../schemas/raw_oauth_state/index.ts | 8 + .../schemas/raw_oauth_state/v1.ts | 20 + .../plugins/shared/actions/server/types.ts | 2 + .../application/hooks/use_oauth_authorize.tsx | 42 ++ .../action_connector_api/oauth_authorize.ts | 32 ++ .../application/lib/check_oauth_auth_code.ts | 26 ++ .../edit_connector_flyout/footer.tsx | 81 ++-- .../edit_connector_flyout/index.tsx | 36 ++ 35 files changed, 2024 insertions(+), 83 deletions(-) create mode 100644 src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts create mode 100644 x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts create mode 100644 x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts create mode 100644 x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts create mode 100644 x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts create mode 100644 x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts create mode 100644 x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts create mode 100644 x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts create mode 100644 x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/oauth_state_model_versions.ts create mode 100644 x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/index.ts create mode 100644 x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts create mode 100644 x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx create mode 100644 x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/action_connector_api/oauth_authorize.ts create mode 100644 x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/check_oauth_auth_code.ts diff --git a/docs/reference/connectors-kibana/sharepoint-online-action-type.md b/docs/reference/connectors-kibana/sharepoint-online-action-type.md index c8dfca29d3301..7c575fc469cdf 100644 --- a/docs/reference/connectors-kibana/sharepoint-online-action-type.md +++ b/docs/reference/connectors-kibana/sharepoint-online-action-type.md @@ -19,16 +19,13 @@ You can create connectors in **{{stack-manage-app}} > {{connectors-ui}}**. For e SharePoint Online connectors have the following configuration properties: -Region -: The geographic region where your SharePoint tenant is hosted. Required for search operations. Valid values: - - `NAM` - North America - - `EUR` - Europe - - `APC` - Asia Pacific - - `LAM` - Latin America - - `MEA` - Middle East and Africa +Authorization URL +: The OAuth 2.0 authorization endpoint URL. Use the format: `https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize` + Replace `{tenant-id}` with your actual Microsoft Entra tenant ID. Token URL : The OAuth 2.0 token endpoint URL. Use the format: `https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token` + Replace `{tenant-id}` with your actual Microsoft Entra tenant ID. Client ID : The application (client) ID from your Microsoft Entra app registration. @@ -36,6 +33,11 @@ Client ID Client Secret : The client secret generated for your Microsoft Entra application. +Scope +: The OAuth scopes to request. Default: `https://graph.microsoft.com/.default offline_access` + - `https://graph.microsoft.com/.default` - Requests all delegated permissions configured for your app + - `offline_access` - Allows the connector to refresh access tokens automatically + ## Test connectors [sharepoint-online-action-configuration] @@ -51,39 +53,123 @@ Search - **size** (optional): Number of results to return. +## Authorize the connector [sharepoint-online-authorization] + +The SharePoint Online connector uses OAuth 2.0 Authorization Code Grant flow, which requires user authorization through Microsoft login. + +After saving the connector configuration, click the **Authorize** button in the connector settings. This will: + +1. Open a new browser window with Microsoft login +2. Prompt you to sign in with your Microsoft 365 account +3. Ask you to consent to the requested permissions +4. Redirect back to {{kib}} with an authorization code +5. Automatically exchange the code for access and refresh tokens + +The connector will automatically refresh tokens when they expire. If you see authentication errors, click **Authorize** again to re-authenticate. + ## Get API credentials [sharepoint-online-api-credentials] -To use the SharePoint Online connector, you need to: - -1. Register an application in Microsoft Entra (Azure AD): - - Go to the [Azure Portal](https://portal.azure.com/) - - Navigate to **Microsoft Entra ID** > **App registrations** - - Click **New registration** - - Provide a name for your application - - Select **Accounts in this organizational directory only** - - Click **Register** - -2. Configure API permissions: - - In your app registration, go to **API permissions** - - Click **Add a permission** > **Microsoft Graph** > **Application permissions** - - Add the following permissions: - - `Sites.Read.All` - Read items in all site collections - - `Sites.ReadWrite.All` - Read and write items in all site collections (if write operations needed) - - Click **Grant admin consent** for your organization - -3. Create a client secret: - - In your app registration, go to **Certificates & secrets** - - Click **New client secret** - - Provide a description and select an expiration period - - Click **Add** - - Copy the secret value immediately (it won't be shown again) - -4. Gather the following information for the connector configuration: - - **Region**: Select the geographic region where your Microsoft 365 tenant is hosted: - - Check your SharePoint URL (e.g., `contoso.sharepoint.com` vs `contoso-my.sharepoint.eu`) - - Common mappings: `.com` domains typically use `NAM`, `.eu` domains use `EUR` - - If unsure, check your Microsoft 365 admin center under **Settings** > **Org settings** > **Organization profile** - - **Tenant ID**: Found in **Overview** section of your app registration (needed for Token URL) - - **Token URL**: Construct using the format `https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token` - - **Client ID**: Found in **Overview** section (also called Application ID) - - **Client Secret**: The value you copied in step 3 (this is the only sensitive field) +To use the SharePoint Online connector, you need to create an app registration in Microsoft Entra (Azure AD) with OAuth 2.0 Authorization Code Grant flow: + +### Step 1: Register an application + +1. Go to the [Azure Portal](https://portal.azure.com/) +2. Navigate to **Microsoft Entra ID** > **App registrations** +3. Click **New registration** +4. Provide a name for your application (e.g., "Kibana SharePoint Connector") +5. Under **Supported account types**, select **Accounts in this organizational directory only** +6. Under **Redirect URI**: + - Select **Web** as the platform + - Enter your Kibana callback URL: `https://your-kibana-domain/internal/actions/connector/_oauth_callback` + - Replace `your-kibana-domain` with your actual Kibana domain (e.g., `https://localhost:5601` for local development) + - This must match the `server.publicBaseUrl` setting in your `kibana.yml` +7. Click **Register** + +### Step 2: Configure API permissions (DELEGATED permissions) + +**Important:** For OAuth Authorization Code flow, you must use **Delegated permissions**, not Application permissions. + +1. In your app registration, go to **API permissions** +2. Click **Add a permission** > **Microsoft Graph** > **Delegated permissions** +3. Add the following permissions: + - `Sites.Read.All` - Read items in all site collections + - `User.Read` - Sign in and read user profile (added by default) +4. Click **Add permissions** +5. Click **Grant admin consent for [your organization]** + - This step requires admin privileges + - Without admin consent, each user will need to consent individually + +**Why these permissions:** +- `Sites.Read.All` (delegated) - Required for the Microsoft Graph Search API to search SharePoint sites, lists, and documents on behalf of the signed-in user +- `User.Read` (delegated) - Required for basic user authentication + +**Note:** The connector uses the scope `https://graph.microsoft.com/.default`, which automatically includes all delegated permissions you've granted to the app. + +### Step 3: Create a client secret + +1. In your app registration, go to **Certificates & secrets** +2. Click **New client secret** +3. Provide a description (e.g., "Kibana SharePoint Connector Secret") +4. Select an expiration period (recommendation: 24 months) +5. Click **Add** +6. **Important:** Copy the secret **Value** immediately - it won't be shown again + - The **Secret ID** is not the same as the secret value + +### Step 4: Gather configuration information + +Collect the following values to configure your connector: + +**Tenant ID:** +- Found in **Microsoft Entra ID** > **Overview** > **Tenant ID** +- Or in your app registration **Overview** > **Directory (tenant) ID** + +**Client ID:** +- Found in your app registration **Overview** > **Application (client) ID** + +**Client Secret:** +- The value you copied in Step 3 + +**Authorization URL:** +- Format: `https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize` +- Replace `{tenant-id}` with your actual Tenant ID +- Example: `https://login.microsoftonline.com/12345678-1234-1234-1234-123456789abc/oauth2/v2.0/authorize` + +**Token URL:** +- Format: `https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token` +- Replace `{tenant-id}` with your actual Tenant ID +- Example: `https://login.microsoftonline.com/12345678-1234-1234-1234-123456789abc/oauth2/v2.0/token` + +**Scope:** +- Default: `https://graph.microsoft.com/.default offline_access` +- Do not modify unless you have specific requirements + +**Note:** The Region parameter is not supported when using OAuth Authorization Code flow with delegated permissions. If you need to use the Region parameter, you must use Application permissions (Client Credentials flow) instead. + +## Common issues [sharepoint-online-troubleshooting] + +**Authentication failed (HTTP 401)** + +This error typically means: +- The access token has expired, been revoked, or doesn't have required scopes +- **Solution:** Click the **Authorize** button again to re-authenticate + +**Invalid redirect URI** + +If authorization fails with a redirect URI error: +- Ensure the redirect URI in your app registration matches `https://your-kibana-domain/internal/actions/connector/_oauth_callback` +- Verify `server.publicBaseUrl` is set correctly in `kibana.yml` +- The redirect URI must be registered as **Web** platform, not **Single-page application** + +**Missing permissions** + +If searches return no results or permission errors: +- Verify you added **Delegated permissions**, not Application permissions +- Ensure admin consent was granted +- Check that `Sites.Read.All` delegated permission is present in **API permissions** + +**Token doesn't have required scopes** + +If you see scope-related errors: +- Verify the Scope field includes `https://graph.microsoft.com/.default offline_access` +- Re-authorize the connector after adding missing permissions in Azure AD +- Ensure admin consent was granted for all delegated permissions diff --git a/src/platform/packages/shared/kbn-connector-specs/src/all_auth_types.ts b/src/platform/packages/shared/kbn-connector-specs/src/all_auth_types.ts index 1e775f3b059de..e89829a2b227d 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/all_auth_types.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/all_auth_types.ts @@ -12,6 +12,7 @@ export * from './auth_types/bearer'; export * from './auth_types/basic'; export * from './auth_types/none'; export * from './auth_types/oauth'; +export * from './auth_types/oauth_authorization_code'; // Skipping PFX and CRT exports for now as they will require updates to // the formbuilder to support file upload fields. diff --git a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts new file mode 100644 index 0000000000000..67493ccc57114 --- /dev/null +++ b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts @@ -0,0 +1,112 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { z } from '@kbn/zod/v4'; +import type { AxiosInstance } from 'axios'; +import type { AuthContext, AuthTypeSpec } from '../connector_spec'; +import * as i18n from './translations'; + +const authSchema = z + .object({ + authorizationUrl: z.url().meta({ label: i18n.OAUTH_AUTHORIZATION_URL_LABEL }), + tokenUrl: z.url().meta({ label: i18n.OAUTH_TOKEN_URL_LABEL }), + clientId: z + .string() + .min(1, { message: i18n.OAUTH_CLIENT_ID_REQUIRED_MESSAGE }) + .meta({ label: i18n.OAUTH_CLIENT_ID_LABEL }), + scope: z.string().meta({ label: i18n.OAUTH_SCOPE_LABEL }).optional(), + clientSecret: z + .string() + .min(1, { message: i18n.OAUTH_CLIENT_SECRET_REQUIRED_MESSAGE }) + .meta({ label: i18n.OAUTH_CLIENT_SECRET_LABEL, sensitive: true }), + }) + .meta({ label: i18n.OAUTH_AUTHORIZATION_CODE_LABEL }); + +type AuthSchemaType = z.infer; + +/** + * OAuth2 Authorization Code Flow with PKCE + * + * This is a generic, reusable auth type for any OAuth2 provider that supports the + * Authorization Code flow (Microsoft, Google, Salesforce, Slack, etc.). + * + * ## How it works: + * 1. User clicks the "Authorize" button in the connector UI + * 2. oauth_authorize route generates PKCE parameters and redirects the user to the provider's authorization page + * 3. User authorizes the app on the provider's site + * 4. Provider redirects back to the oauth_callback route with the authorization code + * 5. Callback route exchanges code for access/refresh tokens and stores them + * 6. Tokens are auto-refreshed when expired during connector execution + * + * ## Usage in connector specs: + * Different providers use different OAuth endpoints - specify these in your connector's auth defaults: + * + * ```typescript + * // Example: Microsoft/SharePoint + * auth: { + * types: [{ + * type: 'oauth_authorization_code', + * defaults: { + * authorizationUrl: 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize', + * tokenUrl: 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token', + * scope: 'https://graph.microsoft.com/.default offline_access' + * } + * }] + * } + * + * // Example: Google Drive + * auth: { + * types: [{ + * type: 'oauth_authorization_code', + * defaults: { + * authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth', + * tokenUrl: 'https://oauth2.googleapis.com/token', + * scope: 'https://www.googleapis.com/auth/drive.readonly' + * } + * }] + * } + * ``` + * + * Users will fill in their client ID, client secret, and can customize URLs/scopes if needed. + * The oauth_authorize and oauth_callback routes are generic and work with any provider. + */ +export const OAuthAuthorizationCode: AuthTypeSpec = { + id: 'oauth_authorization_code', + schema: authSchema, + configure: async ( + ctx: AuthContext, + axiosInstance: AxiosInstance, + secret: AuthSchemaType + ): Promise => { + // For authorization code flow, tokens are managed separately via callback routes + // The getToken() method will retrieve already-stored tokens and auto-refresh if needed + let token; + try { + token = await ctx.getToken({ + tokenUrl: secret.tokenUrl, + scope: secret.scope, + clientId: secret.clientId, + clientSecret: secret.clientSecret, + }); + } catch (error) { + throw new Error( + `Unable to retrieve/refresh the access token. User may need to re-authorize: ${error.message}` + ); + } + + if (!token) { + throw new Error(`No access token available. User must complete OAuth authorization flow.`); + } + + // set global defaults + axiosInstance.defaults.headers.common.Authorization = token; + + return axiosInstance; + }, +}; diff --git a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts index 6ea633f563d8c..c2975aea9ad5f 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts @@ -117,6 +117,20 @@ export const OAUTH_CLIENT_SECRET_REQUIRED_MESSAGE = i18n.translate( } ); +export const OAUTH_AUTHORIZATION_CODE_LABEL = i18n.translate( + 'connectorSpecs.oauthAuthorizationCode.label', + { + defaultMessage: 'OAuth2 Authorization Code', + } +); + +export const OAUTH_AUTHORIZATION_URL_LABEL = i18n.translate( + 'connectorSpecs.oauthAuthorizationUrl.label', + { + defaultMessage: 'Authorization URL', + } +); + export const CRT_AUTH_LABEL = i18n.translate('connectorSpecs.crt.label', { defaultMessage: 'SSL CRT and Key authentication', }); diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts index bee9a5bdef995..d8abf219e9d12 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts @@ -11,6 +11,9 @@ import { i18n } from '@kbn/i18n'; import { z } from '@kbn/zod/v4'; import type { ConnectorSpec } from '../../connector_spec'; +/** + * SharePoint Online connector using OAuth2 Authorization Code flow with Microsoft Identity Platform. + */ export const SharepointOnline: ConnectorSpec = { metadata: { id: '.sharepointOnline', @@ -25,23 +28,18 @@ export const SharepointOnline: ConnectorSpec = { auth: { types: [ { - type: 'oauth_client_credentials', + type: 'oauth_authorization_code', defaults: { - scope: 'https://graph.microsoft.com/.default', + authorizationUrl: 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize', tokenUrl: 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token', + scope: 'https://graph.microsoft.com/.default offline_access', }, }, ], }, - schema: z.object({ - region: z - .enum(['NAM', 'EUR', 'APC', 'LAM', 'MEA']) - .meta({ label: 'Region' }) - .describe( - 'Geographic region for search queries (NAM=North America, EUR=Europe, APC=Asia Pacific, LAM=Latin America, MEA=Middle East/Africa)' - ), - }), + // No additional configuration needed beyond OAuth credentials + schema: z.object({}), actions: { // https://learn.microsoft.com/en-us/graph/api/search-query @@ -64,8 +62,6 @@ export const SharepointOnline: ConnectorSpec = { size?: number; }; - const config = ctx.config as { region: string }; - const searchRequest = { requests: [ { @@ -73,7 +69,6 @@ export const SharepointOnline: ConnectorSpec = { query: { queryString: typedInput.query, }, - region: config.region, ...(typedInput.from !== undefined && { from: typedInput.from }), ...(typedInput.size !== undefined && { size: typedInput.size }), }, diff --git a/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts b/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts index 39c9f3dd19bb6..b4da502a68231 100644 --- a/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts @@ -69,6 +69,11 @@ import type { GetOAuthClientCredentialsSecrets, } from '../lib/get_oauth_client_credentials_access_token'; import { getOAuthClientCredentialsAccessToken } from '../lib/get_oauth_client_credentials_access_token'; +import { + getOAuthAuthorizationCodeAccessToken, + type GetOAuthAuthorizationCodeConfig, + type GetOAuthAuthorizationCodeSecrets, +} from '../lib/get_oauth_authorization_code_access_token'; import { ACTION_FILTER, formatExecutionKPIResult, @@ -413,6 +418,36 @@ export class ActionsClient { ); throw Boom.badRequest(`Failed to retrieve access token`); } + } else if (type === 'authorization_code') { + const tokenOpts = options as any; // Will add proper typing in route schema + try { + accessToken = await getOAuthAuthorizationCodeAccessToken({ + connectorId: tokenOpts.connectorId, + logger: this.context.logger, + configurationUtilities, + credentials: { + config: tokenOpts.config as GetOAuthAuthorizationCodeConfig, + secrets: tokenOpts.secrets as GetOAuthAuthorizationCodeSecrets, + }, + connectorTokenClient: this.connectorTokenClient, + scope: tokenOpts.scope, + }); + + this.context.logger.debug( + () => + `Successfully retrieved access token using Authorization Code OAuth for connector ${ + tokenOpts.connectorId + } with tokenUrl ${tokenOpts.tokenUrl}` + ); + } catch (err) { + this.context.logger.debug( + () => + `Failed to retrieve access token using Authorization Code OAuth for connector ${ + tokenOpts.connectorId + } with tokenUrl ${tokenOpts.tokenUrl} - ${err.message}` + ); + throw Boom.badRequest(`Failed to retrieve access token`); + } } return { accessToken }; diff --git a/x-pack/platform/plugins/shared/actions/server/constants/saved_objects.ts b/x-pack/platform/plugins/shared/actions/server/constants/saved_objects.ts index 9064b6e71b84f..62143fc239052 100644 --- a/x-pack/platform/plugins/shared/actions/server/constants/saved_objects.ts +++ b/x-pack/platform/plugins/shared/actions/server/constants/saved_objects.ts @@ -9,3 +9,4 @@ export const ACTION_SAVED_OBJECT_TYPE = 'action'; export const ALERT_SAVED_OBJECT_TYPE = 'alert'; export const ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE = 'action_task_params'; export const CONNECTOR_TOKEN_SAVED_OBJECT_TYPE = 'connector_token'; +export const OAUTH_STATE_SAVED_OBJECT_TYPE = 'oauth_state'; diff --git a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts index 308ee75ea5bf8..524f4cae5e344 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts @@ -298,4 +298,136 @@ export class ConnectorTokenClient { }); } } + + /** + * Create new token with refresh token support + */ + public async createWithRefreshToken({ + connectorId, + accessToken, + refreshToken, + expiresAtMillis, + refreshTokenExpiresAtMillis, + tokenType, + }: { + connectorId: string; + accessToken: string; + refreshToken?: string; + expiresAtMillis: string; + refreshTokenExpiresAtMillis?: string; + tokenType?: string; + }): Promise { + const id = SavedObjectsUtils.generateId(); + const createTime = Date.now(); + + try { + const result = await this.unsecuredSavedObjectsClient.create( + CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, + omitBy( + { + connectorId, + token: accessToken, + refreshToken, + expiresAt: expiresAtMillis, + refreshTokenExpiresAt: refreshTokenExpiresAtMillis, + tokenType: tokenType ?? 'access_token', + createdAt: new Date(createTime).toISOString(), + updatedAt: new Date(createTime).toISOString(), + }, + isUndefined + ), + { id } + ); + + return result.attributes as ConnectorToken; + } catch (err) { + this.logger.error( + `Failed to create connector_token with refresh token for connectorId "${connectorId}". Error: ${err.message}` + ); + throw err; + } + } + + /** + * Update token with refresh token + */ + public async updateWithRefreshToken({ + id, + token, + refreshToken, + expiresAtMillis, + refreshTokenExpiresAtMillis, + tokenType, + }: { + id: string; + token: string; + refreshToken?: string; + expiresAtMillis: string; + refreshTokenExpiresAtMillis?: string; + tokenType?: string; + }): Promise { + const { attributes, references, version } = + await this.unsecuredSavedObjectsClient.get( + CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, + id + ); + const updateTime = Date.now(); + + try { + const updateOperation = () => { + return this.unsecuredSavedObjectsClient.create( + CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, + omitBy( + { + ...attributes, + token, + refreshToken: refreshToken ?? attributes.refreshToken, + expiresAt: expiresAtMillis, + refreshTokenExpiresAt: + refreshTokenExpiresAtMillis ?? attributes.refreshTokenExpiresAt, + tokenType: tokenType ?? 'access_token', + updatedAt: new Date(updateTime).toISOString(), + }, + isUndefined + ), + omitBy( + { + id, + overwrite: true, + references, + version, + }, + isUndefined + ) + ); + }; + + const result = await retryIfConflicts( + this.logger, + `accessToken.updateWithRefreshToken('${id}')`, + updateOperation, + MAX_RETRY_ATTEMPTS + ); + + return result.attributes as ConnectorToken; + } catch (err) { + this.logger.error( + `Failed to update connector_token with refresh token for id "${id}". Error: ${err.message}` + ); + throw err; + } + } + + /** + * Get refresh token for a connector + */ + public async getRefreshToken({ connectorId }: { connectorId: string }): Promise { + const { connectorToken } = await this.get({ connectorId, tokenType: 'access_token' }); + + if (!connectorToken?.refreshToken) { + return null; + } + + return connectorToken.refreshToken; + } } diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts index 55ae89fc801f8..ed6f516c50da9 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts @@ -16,6 +16,7 @@ import type { ActionsConfigurationUtilities } from '../actions_config'; import type { ConnectorTokenClientContract } from '../types'; import { getBeforeRedirectFn } from './before_redirect'; import { getOAuthClientCredentialsAccessToken } from './get_oauth_client_credentials_access_token'; +import { getOAuthAuthorizationCodeAccessToken } from './get_oauth_authorization_code_access_token'; import { getDeleteTokenAxiosInterceptor } from './delete_token_axios_interceptor'; export type ConnectorInfo = Omit; @@ -98,9 +99,55 @@ export const getAxiosInstanceWithAuth = ({ axiosInstance.interceptors.response.use(onFulfilled, onRejected); } + // Add response interceptor to handle 401 errors for OAuth connectors + if (authTypeId === 'oauth_authorization_code') { + axiosInstance.interceptors.response.use( + (response) => response, + (error) => { + if (error.response?.status === 401) { + const message = + 'Authentication failed: The access token was rejected by the service (HTTP 401). ' + + 'This usually means the token has expired, been revoked, or does not have the required scopes. ' + + 'Please re-authorize the connector by clicking the "Authorize" button in the connector settings.'; + logger.error( + `OAuth 401 error for connectorId ${connectorId}: ${error.message}. ${message}` + ); + error.message = message; + } + return Promise.reject(error); + } + ); + } + const configureCtx = { getCustomHostSettings: (url: string) => configurationUtilities.getCustomHostSettings(url), getToken: async (opts: GetTokenOpts) => { + // Use different token retrieval method based on auth type + if (authTypeId === 'oauth_authorization_code') { + // For authorization code flow, retrieve stored tokens from callback + if (!connectorTokenClient) { + throw new Error('ConnectorTokenClient is required for OAuth authorization code flow'); + } + return await getOAuthAuthorizationCodeAccessToken({ + connectorId, + logger, + configurationUtilities, + credentials: { + config: { + clientId: opts.clientId, + tokenUrl: opts.tokenUrl, + ...(opts.additionalFields ? { additionalFields: opts.additionalFields } : {}), + }, + secrets: { + clientSecret: opts.clientSecret, + }, + }, + connectorTokenClient, + scope: opts.scope, + }); + } + + // For client credentials flow, request new token each time return await getOAuthClientCredentialsAccessToken({ connectorId, logger, diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts new file mode 100644 index 0000000000000..cd8dfba58ec2d --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts @@ -0,0 +1,148 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from '@kbn/core/server'; +import type { ActionsConfigurationUtilities } from '../actions_config'; +import type { ConnectorTokenClientContract } from '../types'; +import { requestOAuthRefreshToken } from './request_oauth_refresh_token'; + +export interface GetOAuthAuthorizationCodeConfig { + clientId: string; + tokenUrl: string; + additionalFields?: Record; +} + +export interface GetOAuthAuthorizationCodeSecrets { + clientSecret: string; +} + +interface GetOAuthAuthorizationCodeAccessTokenOpts { + connectorId: string; + logger: Logger; + configurationUtilities: ActionsConfigurationUtilities; + credentials: { + config: GetOAuthAuthorizationCodeConfig; + secrets: GetOAuthAuthorizationCodeSecrets; + }; + connectorTokenClient: ConnectorTokenClientContract; + scope?: string; +} + +/** + * Get access token for OAuth2 Authorization Code flow + * Automatically refreshes expired tokens using refresh token + */ +export const getOAuthAuthorizationCodeAccessToken = async ({ + connectorId, + logger, + configurationUtilities, + credentials, + connectorTokenClient, + scope, +}: GetOAuthAuthorizationCodeAccessTokenOpts): Promise => { + const { clientId, tokenUrl, additionalFields } = credentials.config; + const { clientSecret } = credentials.secrets; + + if (!clientId || !clientSecret) { + logger.warn(`Missing required fields for requesting OAuth Authorization Code access token`); + return null; + } + + // Get stored token + const { connectorToken, hasErrors } = await connectorTokenClient.get({ + connectorId, + tokenType: 'access_token', + }); + + if (hasErrors) { + logger.warn(`Errors fetching connector token for connectorId: ${connectorId}`); + return null; + } + + // No token found - user must authorize first + if (!connectorToken) { + logger.warn( + `No access token found for connectorId: ${connectorId}. User must complete OAuth authorization flow.` + ); + return null; + } + + // Check if access token is still valid + const now = Date.now(); + const expiresAt = Date.parse(connectorToken.expiresAt); + + if (expiresAt > now) { + // Token still valid + logger.debug(`Using stored access token for connectorId: ${connectorId}`); + return connectorToken.token; + } + + // Access token expired - attempt refresh + if (!connectorToken.refreshToken) { + logger.warn( + `Access token expired and no refresh token available for connectorId: ${connectorId}. User must re-authorize.` + ); + return null; + } + + // Check if refresh token is expired + if ( + connectorToken.refreshTokenExpiresAt && + Date.parse(connectorToken.refreshTokenExpiresAt) <= now + ) { + logger.warn(`Refresh token expired for connectorId: ${connectorId}. User must re-authorize.`); + return null; + } + + // Refresh the token + logger.debug(`Refreshing access token for connectorId: ${connectorId}`); + const requestTokenStart = Date.now(); + + try { + const tokenResult = await requestOAuthRefreshToken( + tokenUrl, + logger, + { + refreshToken: connectorToken.refreshToken, + clientId, + clientSecret, + scope, + ...additionalFields, + }, + configurationUtilities + ); + + const newAccessToken = `${tokenResult.tokenType} ${tokenResult.accessToken}`; + const newRefreshToken = tokenResult.refreshToken || connectorToken.refreshToken; + + // Calculate expiration times + const accessTokenExpiresAt = new Date( + requestTokenStart + tokenResult.expiresIn * 1000 + ).toISOString(); + + const refreshTokenExpiresAt = tokenResult.refreshTokenExpiresIn + ? new Date(requestTokenStart + tokenResult.refreshTokenExpiresIn * 1000).toISOString() + : connectorToken.refreshTokenExpiresAt; + + // Update stored token + await connectorTokenClient.updateWithRefreshToken({ + id: connectorToken.id!, + token: newAccessToken, + refreshToken: newRefreshToken, + expiresAtMillis: accessTokenExpiresAt, + refreshTokenExpiresAtMillis: refreshTokenExpiresAt, + tokenType: 'access_token', + }); + + return newAccessToken; + } catch (err) { + logger.error( + `Failed to refresh access token for connectorId: ${connectorId}. Error: ${err.message}` + ); + return null; + } +}; diff --git a/x-pack/platform/plugins/shared/actions/server/lib/index.ts b/x-pack/platform/plugins/shared/actions/server/lib/index.ts index 58f966cfc7b5b..d2fd2a34a9752 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/index.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/index.ts @@ -44,3 +44,5 @@ export type { TelemetryMetadata } from './token_tracking/gen_ai_token_tracking'; export { formatZodError } from './format_zod_error'; export { createConnectorTypeFromSpec } from './single_file_connectors/create_connector_from_spec'; export { getDeleteTokenAxiosInterceptor } from './delete_token_axios_interceptor'; +export { OAuthAuthorizationService } from './oauth_authorization_service'; +export type { OAuthConfig } from './oauth_authorization_service'; diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts new file mode 100644 index 0000000000000..cbcaf1ce94f66 --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts @@ -0,0 +1,182 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from '@kbn/core/server'; +import type { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; +import type { ActionsClient } from '../actions_client'; +import { INTERNAL_BASE_ACTION_API_PATH } from '../../common'; + +/** + * OAuth connector secrets stored in encrypted saved objects + */ +interface OAuthConnectorSecrets { + authorizationUrl?: string; + clientId?: string; + clientSecret?: string; + tokenUrl?: string; + scope?: string; +} + +/** + * OAuth connector configuration + */ +interface OAuthConnectorConfig { + authType?: string; + auth?: { + type?: string; + }; + authorizationUrl?: string; + clientId?: string; + tokenUrl?: string; + scope?: string; +} + +/** + * OAuth configuration required for authorization flow + */ +export interface OAuthConfig { + authorizationUrl: string; + clientId: string; + scope?: string; +} + +/** + * Parameters for building an OAuth authorization URL + */ +interface BuildAuthorizationUrlParams { + authorizationUrl: string; + clientId: string; + scope?: string; + redirectUri: string; + state: string; + codeChallenge: string; +} + +/** + * Service for handling OAuth2 Authorization Code flow operations + * + * This service encapsulates the business logic for: + * - Validating connectors use OAuth Authorization Code flow + * - Retrieving OAuth configuration with decrypted secrets + * - Building OAuth authorization URLs with PKCE parameters + */ +export class OAuthAuthorizationService { + /** + * Creates an instance of OAuthAuthorizationService + * @param actionsClient - Client for interacting with connectors + * @param encryptedSavedObjectsClient - Client for accessing encrypted connector secrets + * @param kibanaBaseUrl - The public base URL of the Kibana instance + * @param logger - Logger instance for debugging + */ + constructor( + private readonly actionsClient: ActionsClient, + private readonly encryptedSavedObjectsClient: EncryptedSavedObjectsClient, + private readonly kibanaBaseUrl: string, + private readonly logger: Logger + ) {} + + /** + * Validates that a connector uses OAuth Authorization Code flow + * @throws Error if connector doesn't use oauth_authorization_code + */ + private validateOAuthConnector(config: OAuthConnectorConfig): void { + const isOAuthAuthCode = + config?.authType === 'oauth_authorization_code' || + config?.auth?.type === 'oauth_authorization_code'; + + if (!isOAuthAuthCode) { + throw new Error('Connector does not use OAuth Authorization Code flow'); + } + } + + /** + * Gets OAuth configuration for a connector with decrypted secrets + * @param connectorId - The connector ID + * @returns OAuth configuration including authorizationUrl, clientId, and optional scope + * @throws Error if connector is not found, not OAuth, or missing required config + */ + async getOAuthConfig(connectorId: string): Promise { + // Get connector to verify it exists and check auth type + const connector = await this.actionsClient.get({ id: connectorId }); + const config = connector.config as OAuthConnectorConfig; + + // Validate this is an OAuth connector + this.validateOAuthConnector(config); + + // Fetch connector with decrypted secrets + const rawAction = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<{ + actionTypeId: string; + name: string; + config: OAuthConnectorConfig; + secrets: OAuthConnectorSecrets; + }>('action', connectorId); + + const secrets = rawAction.attributes.secrets; + + // Extract OAuth config - for connector specs, check secrets first, then config + const authorizationUrl = secrets.authorizationUrl || config?.authorizationUrl; + const clientId = secrets.clientId || config?.clientId; + const scope = secrets.scope || config?.scope; + + if (!authorizationUrl || !clientId) { + throw new Error( + 'Connector missing required OAuth configuration (authorizationUrl, clientId)' + ); + } + + this.logger.debug(`Retrieved OAuth config for connector ${connectorId}`); + + return { + authorizationUrl, + clientId, + scope, + }; + } + + /** + * Builds the redirect URI for OAuth callbacks + * + * The redirect URI is where the OAuth provider will send the user after authorization. + * It points to the oauth_callback route in this Kibana instance. + * + * @returns The complete redirect URI + * @throws Error if Kibana public base URL is not configured + */ + getRedirectUri(): string { + if (!this.kibanaBaseUrl) { + throw new Error( + 'Kibana public URL not configured. Please set server.publicBaseUrl in kibana.yml' + ); + } + return `${this.kibanaBaseUrl}${INTERNAL_BASE_ACTION_API_PATH}/connector/_oauth_callback`; + } + + /** + * Builds an OAuth authorization URL with PKCE parameters + * @param params - Parameters for building the authorization URL + * @returns The complete authorization URL as a string + */ + buildAuthorizationUrl(params: BuildAuthorizationUrlParams): string { + const { authorizationUrl, clientId, scope, redirectUri, state, codeChallenge } = params; + + const authUrl = new URL(authorizationUrl); + authUrl.searchParams.set('client_id', clientId); + authUrl.searchParams.set('response_type', 'code'); + authUrl.searchParams.set('redirect_uri', redirectUri); + authUrl.searchParams.set('state', state); + authUrl.searchParams.set('code_challenge', codeChallenge); + authUrl.searchParams.set('code_challenge_method', 'S256'); + + if (scope) { + authUrl.searchParams.set('scope', scope); + } + + this.logger.debug(`Built OAuth authorization URL for client ${clientId}`); + + return authUrl.toString(); + } +} diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts new file mode 100644 index 0000000000000..086c6930db3eb --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts @@ -0,0 +1,208 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import crypto from 'crypto'; +import { omitBy, isUndefined } from 'lodash'; +import type { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; +import type { Logger, SavedObjectsClientContract } from '@kbn/core/server'; +import { SavedObjectsUtils } from '@kbn/core/server'; +import { OAUTH_STATE_SAVED_OBJECT_TYPE } from '../constants/saved_objects'; + +const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes + +export interface OAuthState { + id?: string; + state: string; + codeVerifier: string; + connectorId: string; + redirectUri: string; + authorizationUrl: string; + scope?: string; + createdAt: string; + expiresAt: string; + createdBy?: string; +} + +interface ConstructorOptions { + encryptedSavedObjectsClient: EncryptedSavedObjectsClient; + unsecuredSavedObjectsClient: SavedObjectsClientContract; + logger: Logger; +} + +interface CreateStateOptions { + connectorId: string; + redirectUri: string; + authorizationUrl: string; + scope?: string; + createdBy?: string; +} + +/** + * Generates a cryptographically secure random string for OAuth2 state/verifier + */ +function generateRandomString(length: number = 32): string { + return crypto.randomBytes(length).toString('base64url'); +} + +/** + * Generates PKCE code challenge from code verifier + */ +function generateCodeChallenge(codeVerifier: string): string { + return crypto.createHash('sha256').update(codeVerifier).digest('base64url'); +} + +export class OAuthStateClient { + private readonly logger: Logger; + private readonly unsecuredSavedObjectsClient: SavedObjectsClientContract; + private readonly encryptedSavedObjectsClient: EncryptedSavedObjectsClient; + + constructor({ + unsecuredSavedObjectsClient, + encryptedSavedObjectsClient, + logger, + }: ConstructorOptions) { + this.encryptedSavedObjectsClient = encryptedSavedObjectsClient; + this.unsecuredSavedObjectsClient = unsecuredSavedObjectsClient; + this.logger = logger; + } + + /** + * Create new OAuth state with PKCE parameters + */ + public async create({ + connectorId, + redirectUri, + authorizationUrl, + scope, + createdBy, + }: CreateStateOptions): Promise<{ + state: OAuthState; + codeChallenge: string; + }> { + const id = SavedObjectsUtils.generateId(); + const state = generateRandomString(32); + const codeVerifier = generateRandomString(128); // PKCE spec recommends 43-128 chars + const codeChallenge = generateCodeChallenge(codeVerifier); + const now = new Date(); + const expiresAt = new Date(now.getTime() + STATE_EXPIRATION_MS); + + try { + const result = await this.unsecuredSavedObjectsClient.create( + OAUTH_STATE_SAVED_OBJECT_TYPE, + omitBy( + { + state, + codeVerifier, + connectorId, + redirectUri, + authorizationUrl, + scope, + createdAt: now.toISOString(), + expiresAt: expiresAt.toISOString(), + createdBy, + }, + isUndefined + ), + { id } + ); + + return { + state: { + id: result.id, + ...result.attributes, + } as OAuthState, + codeChallenge, + }; + } catch (err) { + this.logger.error( + `Failed to create OAuth state for connectorId "${connectorId}". Error: ${err.message}` + ); + throw err; + } + } + + /** + * Get and validate OAuth state by state parameter + */ + public async get(stateParam: string): Promise { + try { + const result = await this.unsecuredSavedObjectsClient.find({ + type: OAUTH_STATE_SAVED_OBJECT_TYPE, + filter: `${OAUTH_STATE_SAVED_OBJECT_TYPE}.attributes.state: "${stateParam}"`, + perPage: 1, + }); + + if (result.saved_objects.length === 0) { + this.logger.warn(`OAuth state not found for state parameter: ${stateParam}`); + return null; + } + + const stateObject = result.saved_objects[0]; + + // Check if expired + if (new Date(stateObject.attributes.expiresAt) < new Date()) { + this.logger.warn(`OAuth state expired for state parameter: ${stateParam}`); + await this.delete(stateObject.id); + return null; + } + + // Decrypt code verifier + const decrypted = + await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser( + OAUTH_STATE_SAVED_OBJECT_TYPE, + stateObject.id + ); + + return { + id: stateObject.id, + ...decrypted.attributes, + }; + } catch (err) { + this.logger.error( + `Failed to fetch OAuth state for state parameter "${stateParam}". Error: ${err.message}` + ); + return null; + } + } + + /** + * Delete OAuth state (should be called after successful token exchange) + */ + public async delete(id: string): Promise { + try { + await this.unsecuredSavedObjectsClient.delete(OAUTH_STATE_SAVED_OBJECT_TYPE, id); + } catch (err) { + this.logger.error(`Failed to delete OAuth state "${id}". Error: ${err.message}`); + throw err; + } + } + + /** + * Clean up expired OAuth states (called periodically) + */ + public async cleanupExpiredStates(): Promise { + try { + const result = await this.unsecuredSavedObjectsClient.find({ + type: OAUTH_STATE_SAVED_OBJECT_TYPE, + filter: `${OAUTH_STATE_SAVED_OBJECT_TYPE}.attributes.expiresAt < "${new Date().toISOString()}"`, + perPage: 100, + }); + + await Promise.all( + result.saved_objects.map(async (obj) => + this.unsecuredSavedObjectsClient.delete(OAUTH_STATE_SAVED_OBJECT_TYPE, obj.id) + ) + ); + + this.logger.debug(`Cleaned up ${result.saved_objects.length} expired OAuth states`); + return result.saved_objects.length; + } catch (err) { + this.logger.error(`Failed to cleanup expired OAuth states. Error: ${err.message}`); + return 0; + } + } +} diff --git a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts new file mode 100644 index 0000000000000..f69a91c3d547a --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from '@kbn/core/server'; +import type { ActionsConfigurationUtilities } from '../actions_config'; +import type { OAuthTokenResponse } from './request_oauth_token'; +import { requestOAuthToken } from './request_oauth_token'; +import type { AsApiContract } from '../../common'; + +export const OAUTH_AUTHORIZATION_CODE_GRANT_TYPE = 'authorization_code'; + +export interface AuthorizationCodeOAuthRequestParams { + code: string; + redirectUri: string; + codeVerifier: string; + clientId: string; + clientSecret: string; + [key: string]: unknown; +} + +const rewriteBodyRequest = (params: AuthorizationCodeOAuthRequestParams) => { + const { code, redirectUri, codeVerifier, clientId, clientSecret, ...rest } = params; + return { + code, + redirect_uri: redirectUri, + code_verifier: codeVerifier, + client_id: clientId, + client_secret: clientSecret, + ...rest, + } as AsApiContract; +}; + +export async function requestOAuthAuthorizationCodeToken( + tokenUrl: string, + logger: Logger, + params: AuthorizationCodeOAuthRequestParams, + configurationUtilities: ActionsConfigurationUtilities +): Promise { + return await requestOAuthToken( + tokenUrl, + OAUTH_AUTHORIZATION_CODE_GRANT_TYPE, + configurationUtilities, + logger, + rewriteBodyRequest(params) + ); +} diff --git a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts new file mode 100644 index 0000000000000..9ef346e3ea196 --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from '@kbn/core/server'; +import type { ActionsConfigurationUtilities } from '../actions_config'; +import type { OAuthTokenResponse } from './request_oauth_token'; +import { requestOAuthToken } from './request_oauth_token'; +import type { AsApiContract } from '../../common'; + +export const OAUTH_REFRESH_TOKEN_GRANT_TYPE = 'refresh_token'; + +export interface RefreshTokenOAuthRequestParams { + refreshToken: string; + clientId: string; + clientSecret: string; + scope?: string; + [key: string]: unknown; +} + +const rewriteBodyRequest = (params: RefreshTokenOAuthRequestParams) => { + const { refreshToken, clientId, clientSecret, ...rest } = params; + return { + refresh_token: refreshToken, + client_id: clientId, + client_secret: clientSecret, + ...rest, + } as AsApiContract; +}; + +export async function requestOAuthRefreshToken( + tokenUrl: string, + logger: Logger, + params: RefreshTokenOAuthRequestParams, + configurationUtilities: ActionsConfigurationUtilities +): Promise { + return await requestOAuthToken( + tokenUrl, + OAUTH_REFRESH_TOKEN_GRANT_TYPE, + configurationUtilities, + logger, + rewriteBodyRequest(params) + ); +} diff --git a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts index 984933bb7cc24..69f63b852c346 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts @@ -17,6 +17,8 @@ export interface OAuthTokenResponse { tokenType: string; accessToken: string; expiresIn: number; + refreshToken?: string; + refreshTokenExpiresIn?: number; } export async function requestOAuthToken( @@ -49,6 +51,8 @@ export async function requestOAuthToken( tokenType: res.data.token_type, accessToken: res.data.access_token, expiresIn: res.data.expires_in, + refreshToken: res.data.refresh_token, + refreshTokenExpiresIn: res.data.refresh_token_expires_in, }; } else { const errString = stringify(res.data); diff --git a/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/generate_executor_function.ts b/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/generate_executor_function.ts index c7677d3b04ebd..97be08e8d1f7a 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/generate_executor_function.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/generate_executor_function.ts @@ -79,6 +79,12 @@ export const generateExecutorFunction = ({ return { status: 'ok', data, actionId: connectorId }; } catch (error) { logger.error(`error on ${connectorId} event: ${error}`); - return errorResultUnexpectedError(connectorId); + // Preserve the original error message if available, especially for OAuth 401 errors + const errorMessage = error.message || 'error calling connector, unexpected error'; + return { + status: 'error', + message: errorMessage, + actionId: connectorId, + }; } }; diff --git a/x-pack/platform/plugins/shared/actions/server/plugin.ts b/x-pack/platform/plugins/shared/actions/server/plugin.ts index fdb6c48bff20c..8ddd07f7f23d5 100644 --- a/x-pack/platform/plugins/shared/actions/server/plugin.ts +++ b/x-pack/platform/plugins/shared/actions/server/plugin.ts @@ -379,6 +379,12 @@ export class ActionsPlugin licenseState: this.licenseState, actionsConfigUtils, usageCounter: this.usageCounter, + logger: this.logger, + core, + getEncryptedSavedObjects: async () => { + const [, { encryptedSavedObjects }] = await core.getStartServices(); + return encryptedSavedObjects; + }, }); return { diff --git a/x-pack/platform/plugins/shared/actions/server/routes/get_oauth_access_token.ts b/x-pack/platform/plugins/shared/actions/server/routes/get_oauth_access_token.ts index aa91aa5980f68..76b735a97f82f 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/get_oauth_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/get_oauth_access_token.ts @@ -44,13 +44,37 @@ const oauthClientCredentialsBodySchema = schema.object({ export type OAuthClientCredentialsParams = TypeOf; +const oauthAuthorizationCodeBodySchema = schema.object({ + connectorId: schema.string(), + tokenUrl: schema.string(), + scope: schema.maybe(schema.string()), + config: schema.object({ + clientId: schema.string(), + tokenUrl: schema.string(), + }), + secrets: schema.object({ + clientSecret: schema.string(), + }), +}); + +export type OAuthAuthorizationCodeParams = TypeOf; + const bodySchema = schema.object({ - type: schema.oneOf([schema.literal('jwt'), schema.literal('client')]), + type: schema.oneOf([ + schema.literal('jwt'), + schema.literal('client'), + schema.literal('authorization_code'), + ]), options: schema.conditional( schema.siblingRef('type'), schema.literal('jwt'), oauthJwtBodySchema, - oauthClientCredentialsBodySchema + schema.conditional( + schema.siblingRef('type'), + schema.literal('client'), + oauthClientCredentialsBodySchema, + oauthAuthorizationCodeBodySchema + ) ), }); diff --git a/x-pack/platform/plugins/shared/actions/server/routes/index.ts b/x-pack/platform/plugins/shared/actions/server/routes/index.ts index dc55f669445c6..00c4544c8ce5e 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/index.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/index.ts @@ -7,6 +7,8 @@ import type { IRouter } from '@kbn/core/server'; import type { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import type { EncryptedSavedObjectsPluginStart } from '@kbn/encrypted-saved-objects-plugin/server'; +import type { Logger, CoreSetup } from '@kbn/core/server'; import { getAllConnectorsRoute } from './connector/get_all'; import { getAllConnectorsIncludingSystemRoute } from './connector/get_all_system'; import { listTypesRoute } from './connector/list_types'; @@ -19,19 +21,26 @@ import { executeConnectorRoute } from './connector/execute'; import { getConnectorRoute } from './connector/get'; import { updateConnectorRoute } from './connector/update'; import { getOAuthAccessToken } from './get_oauth_access_token'; +import { oauthAuthorizeRoute } from './oauth_authorize'; +import { oauthCallbackRoute } from './oauth_callback'; import type { ActionsConfigurationUtilities } from '../actions_config'; import { getGlobalExecutionLogRoute } from './get_global_execution_logs'; import { getGlobalExecutionKPIRoute } from './get_global_execution_kpi'; +import type { ActionsPluginsStart } from '../plugin'; + export interface RouteOptions { router: IRouter; licenseState: ILicenseState; actionsConfigUtils: ActionsConfigurationUtilities; usageCounter?: UsageCounter; + getEncryptedSavedObjects?: () => Promise; + logger: Logger; + core: CoreSetup; } export function defineRoutes(opts: RouteOptions) { - const { router, licenseState, actionsConfigUtils } = opts; + const { router, licenseState, actionsConfigUtils, getEncryptedSavedObjects, logger, core } = opts; createConnectorRoute(router, licenseState); deleteConnectorRoute(router, licenseState); @@ -44,6 +53,15 @@ export function defineRoutes(opts: RouteOptions) { getGlobalExecutionKPIRoute(router, licenseState); getOAuthAccessToken(router, licenseState, actionsConfigUtils); + oauthAuthorizeRoute( + router, + licenseState, + actionsConfigUtils, + logger, + core, + getEncryptedSavedObjects + ); + oauthCallbackRoute(router, licenseState, actionsConfigUtils, logger, getEncryptedSavedObjects); getAllConnectorsIncludingSystemRoute(router, licenseState); listTypesWithSystemRoute(router, licenseState); } diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts new file mode 100644 index 0000000000000..634dd47f4b255 --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts @@ -0,0 +1,146 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { TypeOf } from '@kbn/config-schema'; +import { schema } from '@kbn/config-schema'; +import type { IRouter, Logger, CoreSetup } from '@kbn/core/server'; +import type { EncryptedSavedObjectsPluginStart } from '@kbn/encrypted-saved-objects-plugin/server'; +import type { ILicenseState } from '../lib'; +import { INTERNAL_BASE_ACTION_API_PATH } from '../../common'; +import type { ActionsRequestHandlerContext } from '../types'; +import { verifyAccessAndContext } from './verify_access_and_context'; +import type { ActionsConfigurationUtilities } from '../actions_config'; +import { DEFAULT_ACTION_ROUTE_SECURITY } from './constants'; +import { OAuthStateClient } from '../lib/oauth_state_client'; +import { OAuthAuthorizationService } from '../lib/oauth_authorization_service'; +import type { ActionsPluginsStart } from '../plugin'; + +const paramsSchema = schema.object({ + connectorId: schema.string(), +}); + +export type OAuthAuthorizeParams = TypeOf; + +/** + * Initiates OAuth2 Authorization Code flow + * Returns authorization URL for user to visit + */ +export const oauthAuthorizeRoute = ( + router: IRouter, + licenseState: ILicenseState, + configurationUtilities: ActionsConfigurationUtilities, + logger: Logger, + coreSetup: CoreSetup, + getEncryptedSavedObjects?: () => Promise +) => { + router.post( + { + path: `${INTERNAL_BASE_ACTION_API_PATH}/connector/{connectorId}/_oauth_authorize`, + security: DEFAULT_ACTION_ROUTE_SECURITY, + validate: { + params: paramsSchema, + }, + options: { + access: 'internal', + }, + }, + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async function (context, req, res) { + const { connectorId } = req.params; + + try { + const core = await context.core; + const actionsClient = (await context.actions).getActionsClient(); + const routeLogger = logger.get('oauth_authorize'); + + // Get encrypted saved objects client + if (!getEncryptedSavedObjects) { + throw new Error('EncryptedSavedObjects plugin not available'); + } + + const encryptedSavedObjects = await getEncryptedSavedObjects(); + const encryptedSavedObjectsClient = encryptedSavedObjects.getClient({ + includedHiddenTypes: ['action', 'oauth_state'], + }); + + // Get Kibana base URL + const [coreStart] = await coreSetup.getStartServices(); + const kibanaUrl = coreStart.http.basePath.publicBaseUrl; + + if (!kibanaUrl) { + return res.badRequest({ + body: { + message: + 'Kibana public URL not configured. Please set server.publicBaseUrl in kibana.yml', + }, + }); + } + + // Create OAuth authorization service + const oauthService = new OAuthAuthorizationService( + actionsClient, + encryptedSavedObjectsClient, + kibanaUrl, + routeLogger + ); + + // Get OAuth configuration (validates connector and retrieves decrypted config) + const oauthConfig = await oauthService.getOAuthConfig(connectorId); + + // Get redirect URI + const redirectUri = oauthService.getRedirectUri(); + + // Create OAuth state with PKCE + const oauthStateClient = new OAuthStateClient({ + encryptedSavedObjectsClient, + unsecuredSavedObjectsClient: core.savedObjects.getClient({ + includedHiddenTypes: ['oauth_state'], + }), + logger: routeLogger, + }); + + const { state, codeChallenge } = await oauthStateClient.create({ + connectorId, + redirectUri, + authorizationUrl: oauthConfig.authorizationUrl, + scope: oauthConfig.scope, + }); + + // Build authorization URL + const authorizationUrl = oauthService.buildAuthorizationUrl({ + authorizationUrl: oauthConfig.authorizationUrl, + clientId: oauthConfig.clientId, + scope: oauthConfig.scope, + redirectUri, + state: state.state, + codeChallenge, + }); + + return res.ok({ + body: { + authorizationUrl, + state: state.state, + }, + }); + } catch (err) { + const errorMessage = err instanceof Error ? err.message : String(err); + const statusCode = + err instanceof Error && 'statusCode' in err + ? (err as Error & { statusCode: number }).statusCode + : 500; + + return res.customError({ + statusCode, + body: { + message: errorMessage || 'Failed to initiate OAuth authorization', + }, + }); + } + }) + ) + ); +}; diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts new file mode 100644 index 0000000000000..276dbcdb9de9f --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -0,0 +1,367 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { TypeOf } from '@kbn/config-schema'; +import { schema } from '@kbn/config-schema'; +import type { IRouter, Logger } from '@kbn/core/server'; +import type { EncryptedSavedObjectsPluginStart } from '@kbn/encrypted-saved-objects-plugin/server'; +import type { ILicenseState } from '../lib'; +import { INTERNAL_BASE_ACTION_API_PATH } from '../../common'; +import type { ActionsRequestHandlerContext } from '../types'; +import type { ActionsConfigurationUtilities } from '../actions_config'; +import { DEFAULT_ACTION_ROUTE_SECURITY } from './constants'; +import { verifyAccessAndContext } from './verify_access_and_context'; +import { OAuthStateClient } from '../lib/oauth_state_client'; +import { requestOAuthAuthorizationCodeToken } from '../lib/request_oauth_authorization_code_token'; +import { ConnectorTokenClient } from '../lib/connector_token_client'; + +const querySchema = schema.object({ + code: schema.maybe(schema.string()), + state: schema.maybe(schema.string()), + error: schema.maybe(schema.string()), + error_description: schema.maybe(schema.string()), + session_state: schema.maybe(schema.string()), // Microsoft OAuth includes this +}); + +export type OAuthCallbackQuery = TypeOf; + +interface OAuthConnectorSecrets { + clientId?: string; + clientSecret?: string; + tokenUrl?: string; +} + +interface OAuthConnectorConfig { + clientId?: string; + tokenUrl?: string; +} + +/** + * Generates a styled OAuth callback page using EUI-like styling + */ +function generateOAuthCallbackPage({ + title, + heading, + message, + details, + isSuccess, + autoClose, +}: { + title: string; + heading: string; + message: string; + details?: string; + isSuccess: boolean; + autoClose?: boolean; +}): string { + const iconColor = isSuccess ? '#00BFB3' : '#BD271E'; + const icon = isSuccess ? '✓' : '✕'; + + return ` + + + + + + ${title} + + ${ + autoClose + ? `` + : '' + } + + +
+
${icon}
+

${heading}

+

${message}

+ ${details ? `
${details}
` : ''} + ${ + autoClose + ? '' + : '' + } +
+ + + `; +} + +/** + * OAuth2 callback endpoint - handles authorization code exchange + */ +export const oauthCallbackRoute = ( + router: IRouter, + licenseState: ILicenseState, + configurationUtilities: ActionsConfigurationUtilities, + logger: Logger, + getEncryptedSavedObjects?: () => Promise +) => { + router.get( + { + path: `${INTERNAL_BASE_ACTION_API_PATH}/connector/_oauth_callback`, + security: DEFAULT_ACTION_ROUTE_SECURITY, + validate: { + query: querySchema, + }, + options: { + access: 'public', + // authRequired: true is the default - user must have valid session + // The OAuth redirect happens in their browser, so they will have their session cookie + }, + }, + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async function (context, req, res) { + const { code, state: stateParam, error, error_description: errorDescription } = req.query; + + // Handle OAuth errors or missing parameters + if (error || !code || !stateParam) { + const errorMessage = error || 'Missing required OAuth parameters (code or state)'; + const details = errorDescription + ? `${errorMessage}\n\n${errorDescription}` + : errorMessage; + + return res.ok({ + headers: { 'content-type': 'text/html' }, + body: generateOAuthCallbackPage({ + title: 'OAuth Authorization Failed', + heading: 'Authorization Failed', + message: 'You can close this window and try again.', + details, + isSuccess: false, + }), + }); + } + + try { + const core = await context.core; + const routeLogger = logger.get('oauth_callback'); + + // Get encrypted saved objects client + if (!getEncryptedSavedObjects) { + throw new Error('EncryptedSavedObjects plugin not available'); + } + + const encryptedSavedObjects = await getEncryptedSavedObjects(); + const encryptedSavedObjectsClient = encryptedSavedObjects.getClient({ + includedHiddenTypes: ['oauth_state'], + }); + + // Get saved objects client for reading/writing OAuth state and tokens + const unsecuredSavedObjectsClient = core.savedObjects.getClient({ + includedHiddenTypes: ['oauth_state', 'connector_token'], + }); + + // Retrieve and validate state + const oauthStateClient = new OAuthStateClient({ + encryptedSavedObjectsClient, + unsecuredSavedObjectsClient, + logger: routeLogger, + }); + + const oauthState = await oauthStateClient.get(stateParam); + + if (!oauthState) { + return res.ok({ + headers: { 'content-type': 'text/html' }, + body: generateOAuthCallbackPage({ + title: 'OAuth Authorization Failed', + heading: 'Authorization Failed', + message: 'You can close this window and try again.', + details: + 'Invalid or expired state parameter. The authorization session may have timed out.', + isSuccess: false, + }), + }); + } + + // Get connector with decrypted secrets + const connectorEncryptedClient = encryptedSavedObjects.getClient({ + includedHiddenTypes: ['action'], + }); + + const rawAction = await connectorEncryptedClient.getDecryptedAsInternalUser<{ + actionTypeId: string; + name: string; + config: OAuthConnectorConfig; + secrets: OAuthConnectorSecrets; + }>('action', oauthState.connectorId); + + const config = rawAction.attributes.config; + const secrets = rawAction.attributes.secrets; + + // Extract OAuth config - for connector specs, secrets are stored directly + const clientId = secrets.clientId || config?.clientId; + const clientSecret = secrets.clientSecret; + const tokenUrl = secrets.tokenUrl || config?.tokenUrl; + + if (!clientId || !clientSecret || !tokenUrl) { + throw new Error( + 'Connector missing required OAuth configuration (clientId, clientSecret, tokenUrl)' + ); + } + + // Exchange authorization code for tokens + const tokenResult = await requestOAuthAuthorizationCodeToken( + tokenUrl, + logger, + { + code, + redirectUri: oauthState.redirectUri, + codeVerifier: oauthState.codeVerifier, + clientId, + clientSecret, + }, + configurationUtilities + ); + + // Store tokens + const connectorTokenEncryptedClient = encryptedSavedObjects.getClient({ + includedHiddenTypes: ['connector_token'], + }); + + const connectorTokenClient = new ConnectorTokenClient({ + encryptedSavedObjectsClient: connectorTokenEncryptedClient, + unsecuredSavedObjectsClient, + logger: routeLogger, + }); + + const now = Date.now(); + const accessTokenExpiresAt = new Date(now + tokenResult.expiresIn * 1000).toISOString(); + + const refreshTokenExpiresAt = tokenResult.refreshTokenExpiresIn + ? new Date(now + tokenResult.refreshTokenExpiresIn * 1000).toISOString() + : undefined; + + // Delete any existing tokens first + await connectorTokenClient.deleteConnectorTokens({ + connectorId: oauthState.connectorId, + tokenType: 'access_token', + }); + + const formattedToken = `${tokenResult.tokenType} ${tokenResult.accessToken}`; + routeLogger.debug( + `Successfully exchanged authorization code for access token for connectorId: ${oauthState.connectorId}` + ); + + // Create new token record + await connectorTokenClient.createWithRefreshToken({ + connectorId: oauthState.connectorId, + accessToken: formattedToken, + refreshToken: tokenResult.refreshToken, + expiresAtMillis: accessTokenExpiresAt, + refreshTokenExpiresAtMillis: refreshTokenExpiresAt, + tokenType: 'access_token', + }); + + // Clean up state + await oauthStateClient.delete(oauthState.id!); + + // Return success page + return res.ok({ + headers: { 'content-type': 'text/html' }, + body: generateOAuthCallbackPage({ + title: 'OAuth Authorization Successful', + heading: 'Authorization Successful', + message: 'You have successfully authorized the connector.', + details: 'You can now close this window and return to Kibana.', + isSuccess: true, + autoClose: true, + }), + }); + } catch (err) { + const routeLogger = logger.get('oauth_callback'); + const errorMessage = err instanceof Error ? err.message : String(err); + routeLogger.error(`OAuth callback failed: ${errorMessage}`); + if (err instanceof Error && err.stack) { + routeLogger.debug(`OAuth callback error stack: ${err.stack}`); + } + return res.ok({ + headers: { 'content-type': 'text/html' }, + body: generateOAuthCallbackPage({ + title: 'OAuth Authorization Failed', + heading: 'Authorization Failed', + message: 'You can close this window and try again.', + details: errorMessage, + isSuccess: false, + }), + }); + } + }) + ) + ); +}; diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/index.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/index.ts index c7648455e0a80..7b8ad4ea1c3f7 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/index.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/index.ts @@ -13,7 +13,12 @@ import type { import type { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server'; import { getOldestIdleActionTask } from '@kbn/task-manager-plugin/server'; import { ALERTING_CASES_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server'; -import { actionMappings, actionTaskParamsMappings, connectorTokenMappings } from './mappings'; +import { + actionMappings, + actionTaskParamsMappings, + connectorTokenMappings, + oauthStateMappings, +} from './mappings'; import { getActionsMigrations } from './actions_migrations'; import { getActionTaskParamsMigrations } from './action_task_params_migrations'; import type { InMemoryConnector, RawAction } from '../types'; @@ -24,11 +29,13 @@ import { ACTION_SAVED_OBJECT_TYPE, ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, + OAUTH_STATE_SAVED_OBJECT_TYPE, } from '../constants/saved_objects'; import { actionTaskParamsModelVersions, connectorModelVersions, connectorTokenModelVersions, + oauthStateModelVersions, } from './model_versions'; export function setupSavedObjects( @@ -129,13 +136,53 @@ export function setupSavedObjects( encryptedSavedObjects.registerType({ type: CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, - attributesToEncrypt: new Set(['token']), + attributesToEncrypt: new Set(['token', 'refreshToken']), attributesToIncludeInAAD: new Set([ 'connectorId', 'tokenType', 'expiresAt', 'createdAt', 'updatedAt', + 'refreshTokenExpiresAt', + ]), + }); + + savedObjects.registerType({ + name: OAUTH_STATE_SAVED_OBJECT_TYPE, + indexPattern: ALERTING_CASES_SAVED_OBJECT_INDEX, + hidden: true, + namespaceType: 'agnostic', + mappings: oauthStateMappings, + management: { + importableAndExportable: false, + }, + modelVersions: oauthStateModelVersions, + excludeOnUpgrade: async () => { + // Clean up expired states older than 1 hour + const oneHourAgo = new Date(Date.now() - 3600000).toISOString(); + return { + bool: { + must: [ + { term: { type: 'oauth_state' } }, + { range: { expiresAt: { lt: oneHourAgo } } }, + ], + }, + }; + }, + }); + + encryptedSavedObjects.registerType({ + type: OAUTH_STATE_SAVED_OBJECT_TYPE, + attributesToEncrypt: new Set(['codeVerifier']), + attributesToIncludeInAAD: new Set([ + 'state', + 'connectorId', + 'redirectUri', + 'authorizationUrl', + 'scope', + 'createdAt', + 'expiresAt', + 'createdBy', ]), }); } diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/mappings.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/mappings.ts index a39deae207a31..0cd027f431cf4 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/mappings.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/mappings.ts @@ -92,5 +92,45 @@ export const connectorTokenMappings: SavedObjectsTypeMappingDefinition = { // updatedAt: { // type: 'date', // }, + // refreshToken: { + // type: 'binary', + // }, + // refreshTokenExpiresAt: { + // type: 'date', + // }, + }, +}; + +export const oauthStateMappings: SavedObjectsTypeMappingDefinition = { + dynamic: false, + properties: { + state: { + type: 'keyword', + }, + connectorId: { + type: 'keyword', + }, + expiresAt: { + type: 'date', + }, + // NO NEED TO BE INDEXED + // codeVerifier: { + // type: 'binary', + // }, + // redirectUri: { + // type: 'keyword', + // }, + // authorizationUrl: { + // type: 'keyword', + // }, + // scope: { + // type: 'keyword', + // }, + // createdAt: { + // type: 'date', + // }, + // createdBy: { + // type: 'keyword', + // }, }, }; diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/index.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/index.ts index f573864ffbec4..60a0cb4fe4f3f 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/index.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/index.ts @@ -8,3 +8,4 @@ export { connectorModelVersions } from './connector_model_versions'; export { connectorTokenModelVersions } from './connector_token_model_versions'; export { actionTaskParamsModelVersions } from './action_task_params_model_versions'; +export { oauthStateModelVersions } from './oauth_state_model_versions'; diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/oauth_state_model_versions.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/oauth_state_model_versions.ts new file mode 100644 index 0000000000000..598cc40960fa2 --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/oauth_state_model_versions.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SavedObjectsModelVersionMap } from '@kbn/core-saved-objects-server'; +import { rawOAuthStateSchemaV1 } from '../schemas/raw_oauth_state'; + +export const oauthStateModelVersions: SavedObjectsModelVersionMap = { + '1': { + changes: [], + schemas: { + forwardCompatibility: rawOAuthStateSchemaV1.extends({}, { unknowns: 'ignore' }), + create: rawOAuthStateSchemaV1, + }, + }, +}; diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v1.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v1.ts index be91cf266b5bc..21f80e8edc3a8 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v1.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v1.ts @@ -14,4 +14,6 @@ export const rawConnectorTokenSchema = schema.object({ token: schema.string(), tokenType: schema.string(), updatedAt: schema.string(), + refreshToken: schema.maybe(schema.string()), + refreshTokenExpiresAt: schema.maybe(schema.string()), }); diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/index.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/index.ts new file mode 100644 index 0000000000000..cc63d8597a840 --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { rawOAuthStateSchema as rawOAuthStateSchemaV1 } from './v1'; diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts new file mode 100644 index 0000000000000..e3acd0cff6c55 --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const rawOAuthStateSchema = schema.object({ + state: schema.string(), + codeVerifier: schema.string(), + connectorId: schema.string(), + redirectUri: schema.string(), + authorizationUrl: schema.string(), + scope: schema.maybe(schema.string()), + createdAt: schema.string(), + expiresAt: schema.string(), + createdBy: schema.maybe(schema.string()), +}); diff --git a/x-pack/platform/plugins/shared/actions/server/types.ts b/x-pack/platform/plugins/shared/actions/server/types.ts index b424acdaab609..6d1b1bd5b3a89 100644 --- a/x-pack/platform/plugins/shared/actions/server/types.ts +++ b/x-pack/platform/plugins/shared/actions/server/types.ts @@ -272,6 +272,8 @@ export interface ConnectorToken extends SavedObjectAttributes { expiresAt: string; createdAt: string; updatedAt?: string; + refreshToken?: string; + refreshTokenExpiresAt?: string; } // This unallowlist should only contain connector types that require a request or API key for diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx new file mode 100644 index 0000000000000..3a3e630a146e8 --- /dev/null +++ b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useState, useCallback } from 'react'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { oauthAuthorize } from '../lib/action_connector_api/oauth_authorize'; + +export function useOAuthAuthorize() { + const { http } = useKibana().services; + const [isAuthorizing, setIsAuthorizing] = useState(false); + + const authorize = useCallback( + async (connectorId: string) => { + setIsAuthorizing(true); + try { + const { authorizationUrl } = await oauthAuthorize({ + http: http!, + connectorId, + }); + + // Open authorization URL in new tab + window.open(authorizationUrl, '_blank', 'noopener,noreferrer'); + + return true; + } catch (error) { + throw error; + } finally { + setIsAuthorizing(false); + } + }, + [http] + ); + + return { + authorize, + isAuthorizing, + }; +} diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/action_connector_api/oauth_authorize.ts b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/action_connector_api/oauth_authorize.ts new file mode 100644 index 0000000000000..fc7dd565ea77b --- /dev/null +++ b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/action_connector_api/oauth_authorize.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { HttpSetup } from '@kbn/core/public'; +import { INTERNAL_BASE_ACTION_API_PATH } from '../../constants'; + +interface OAuthAuthorizeResponse { + authorizationUrl: string; + state: string; +} + +export async function oauthAuthorize({ + http, + connectorId, +}: { + http: HttpSetup; + connectorId: string; +}): Promise { + const res = await http.post( + `${INTERNAL_BASE_ACTION_API_PATH}/connector/${encodeURIComponent( + connectorId + )}/_oauth_authorize`, + { + body: JSON.stringify({}), + } + ); + return res; +} diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/check_oauth_auth_code.ts b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/check_oauth_auth_code.ts new file mode 100644 index 0000000000000..ff27e852496cd --- /dev/null +++ b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/check_oauth_auth_code.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ActionConnector } from '../../types'; + +/** + * Checks if a connector uses OAuth Authorization Code flow + * @param connector - The connector to check + * @returns True if the connector uses oauth_authorization_code auth type + */ +export function usesOAuthAuthorizationCode(connector: ActionConnector): boolean { + if (!connector || !connector.config) { + return false; + } + + const config = connector.config as Record; + + return ( + config?.authType === 'oauth_authorization_code' || + (config?.auth as Record)?.type === 'oauth_authorization_code' + ); +} diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/footer.tsx b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/footer.tsx index ca9b6e8b583cc..f65f54fd46f3d 100644 --- a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/footer.tsx +++ b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/footer.tsx @@ -15,6 +15,8 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; +import type { ActionConnector } from '../../../../types'; +import { usesOAuthAuthorizationCode } from '../../../lib/check_oauth_auth_code'; interface Props { onClose: () => void; @@ -23,6 +25,9 @@ interface Props { showButtons: boolean; disabled: boolean; onClickSave: () => void; + connector: ActionConnector; + onAuthorize?: () => void; + isAuthorizing?: boolean; } const FlyoutFooterComponent: React.FC = ({ @@ -32,6 +37,9 @@ const FlyoutFooterComponent: React.FC = ({ showButtons, disabled, onClickSave, + connector, + onAuthorize, + isAuthorizing, }) => { return ( @@ -44,29 +52,56 @@ const FlyoutFooterComponent: React.FC = ({ - {showButtons && ( - - {isSaved ? ( - - ) : ( - - )} - - )} + + {usesOAuthAuthorizationCode(connector) && onAuthorize && ( + + + {isAuthorizing ? ( + + ) : ( + + )} + + + )} + {showButtons && ( + + + {isSaved ? ( + + ) : ( + + )} + + + )} + diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx index 88006ce00c80c..d5322a3b8adf0 100644 --- a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx +++ b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx @@ -39,6 +39,7 @@ import { hasSaveActionsCapability } from '../../../lib/capabilities'; import { TestConnectorForm } from '../test_connector_form'; import { ConnectorRulesList } from '../connector_rules_list'; import { useExecuteConnector } from '../../../hooks/use_execute_connector'; +import { useOAuthAuthorize } from '../../../hooks/use_oauth_authorize'; import { FlyoutHeader } from './header'; import { FlyoutFooter } from './footer'; @@ -71,6 +72,7 @@ const EditConnectorFlyoutComponent: React.FC = ({ const { docLinks, application: { capabilities }, + notifications: { toasts }, } = useKibana().services; const isMounted = useRef(false); @@ -116,6 +118,7 @@ const EditConnectorFlyoutComponent: React.FC = ({ const [showConfirmModal, setShowConfirmModal] = useState(false); const [isEdit, setIsEdit] = useState(true); const [isSaved, setIsSaved] = useState(false); + const { authorize, isAuthorizing } = useOAuthAuthorize(); const { preSubmitValidator, submit, isValid: isFormValid, isSubmitting } = formState; const hasErrors = isFormValid === false; const isSaving = isUpdatingConnector || isSubmitting || isExecutingConnector; @@ -224,6 +227,36 @@ const EditConnectorFlyoutComponent: React.FC = ({ onFormModifiedChange, ]); + const handleAuthorize = useCallback(async () => { + if (!connector) return; + + try { + await authorize(connector.id); + + toasts.addSuccess({ + title: i18n.translate( + 'xpack.triggersActionsUI.sections.editConnectorForm.authorizeSuccessTitle', + { defaultMessage: 'Authorization window opened' } + ), + text: i18n.translate( + 'xpack.triggersActionsUI.sections.editConnectorForm.authorizeSuccessText', + { + defaultMessage: + 'Complete the authorization in the new window, then test your connector.', + } + ), + }); + } catch (error) { + toasts.addDanger({ + title: i18n.translate( + 'xpack.triggersActionsUI.sections.editConnectorForm.authorizeErrorTitle', + { defaultMessage: 'Failed to start authorization' } + ), + text: error.message, + }); + } + }, [connector, authorize, toasts]); + useEffect(() => { isMounted.current = true; @@ -363,6 +396,9 @@ const EditConnectorFlyoutComponent: React.FC = ({ disabled={disabled} showButtons={showButtons} onClickSave={onClickSave} + connector={connector} + onAuthorize={handleAuthorize} + isAuthorizing={isAuthorizing} /> {showConfirmModal && ( From 1387a03a86ba61ab06c6f0bf4066607c2e80e14f Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 16 Dec 2025 22:46:54 +0000 Subject: [PATCH 03/49] Changes from node scripts/check_mappings_update --fix --- .../current_fields.json | 5 +++++ .../current_mappings.json | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/packages/kbn-check-saved-objects-cli/current_fields.json b/packages/kbn-check-saved-objects-cli/current_fields.json index d6d85ad416bc5..8be9482f094d5 100644 --- a/packages/kbn-check-saved-objects-cli/current_fields.json +++ b/packages/kbn-check-saved-objects-cli/current_fields.json @@ -910,6 +910,11 @@ "monitoring-telemetry": [ "reportedClusterUuids" ], + "oauth_state": [ + "connectorId", + "expiresAt", + "state" + ], "observability-onboarding-state": [ "progress", "state", diff --git a/packages/kbn-check-saved-objects-cli/current_mappings.json b/packages/kbn-check-saved-objects-cli/current_mappings.json index 9ee2e0fae0119..0e915075480a3 100644 --- a/packages/kbn-check-saved-objects-cli/current_mappings.json +++ b/packages/kbn-check-saved-objects-cli/current_mappings.json @@ -3011,6 +3011,20 @@ } } }, + "oauth_state": { + "dynamic": false, + "properties": { + "connectorId": { + "type": "keyword" + }, + "expiresAt": { + "type": "date" + }, + "state": { + "type": "keyword" + } + } + }, "observability-onboarding-state": { "properties": { "progress": { From 5b3a8cfaf848c98069de23dd2f60dd3656962931 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 16 Dec 2025 22:58:07 +0000 Subject: [PATCH 04/49] Changes from node scripts/eslint_all_files --no-cache --fix --- .../actions/server/actions_client/actions_client.ts | 8 ++------ .../plugins/shared/actions/server/saved_objects/index.ts | 5 +---- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts b/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts index b4da502a68231..96c2926cfb271 100644 --- a/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts @@ -435,16 +435,12 @@ export class ActionsClient { this.context.logger.debug( () => - `Successfully retrieved access token using Authorization Code OAuth for connector ${ - tokenOpts.connectorId - } with tokenUrl ${tokenOpts.tokenUrl}` + `Successfully retrieved access token using Authorization Code OAuth for connector ${tokenOpts.connectorId} with tokenUrl ${tokenOpts.tokenUrl}` ); } catch (err) { this.context.logger.debug( () => - `Failed to retrieve access token using Authorization Code OAuth for connector ${ - tokenOpts.connectorId - } with tokenUrl ${tokenOpts.tokenUrl} - ${err.message}` + `Failed to retrieve access token using Authorization Code OAuth for connector ${tokenOpts.connectorId} with tokenUrl ${tokenOpts.tokenUrl} - ${err.message}` ); throw Boom.badRequest(`Failed to retrieve access token`); } diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/index.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/index.ts index 7b8ad4ea1c3f7..82c342f22d2df 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/index.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/index.ts @@ -162,10 +162,7 @@ export function setupSavedObjects( const oneHourAgo = new Date(Date.now() - 3600000).toISOString(); return { bool: { - must: [ - { term: { type: 'oauth_state' } }, - { range: { expiresAt: { lt: oneHourAgo } } }, - ], + must: [{ term: { type: 'oauth_state' } }, { range: { expiresAt: { lt: oneHourAgo } } }], }, }; }, From f8e4a6117671fc4441d4b28c0160f6e1acd6df9c Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Wed, 24 Dec 2025 16:04:53 +0200 Subject: [PATCH 05/49] Get rid of IDE errors --- .../actions/server/lib/connector_token_client.ts | 12 ++++++++---- .../platform/plugins/shared/actions/server/types.ts | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts index 524f4cae5e344..cc009a44236db 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts @@ -113,10 +113,12 @@ export class ConnectorTokenClient { try { const updateOperation = () => { + // Exclude id from attributes since it's saved object metadata, not document data + const { id: _id, ...attributesWithoutId } = attributes; return this.unsecuredSavedObjectsClient.create( CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, { - ...attributes, + ...attributesWithoutId, token, expiresAt: expiresAtMillis, tokenType: tokenType ?? 'access_token', @@ -291,7 +293,7 @@ export class ConnectorTokenClient { }); } else { await this.update({ - id: token.id!.toString(), + id: token.id!, token: newToken, expiresAtMillis: new Date(tokenRequestDate + expiresInSec * 1000).toISOString(), tokenType: 'access_token', @@ -375,11 +377,13 @@ export class ConnectorTokenClient { try { const updateOperation = () => { + // Exclude id from attributes since it's saved object metadata, not document data + const { id: _id, ...attributesWithoutId } = attributes; return this.unsecuredSavedObjectsClient.create( CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, omitBy( { - ...attributes, + ...attributesWithoutId, token, refreshToken: refreshToken ?? attributes.refreshToken, expiresAt: expiresAtMillis, @@ -389,7 +393,7 @@ export class ConnectorTokenClient { updatedAt: new Date(updateTime).toISOString(), }, isUndefined - ), + ) as ConnectorToken, omitBy( { id, diff --git a/x-pack/platform/plugins/shared/actions/server/types.ts b/x-pack/platform/plugins/shared/actions/server/types.ts index 6d1b1bd5b3a89..1e23cff7f6dd7 100644 --- a/x-pack/platform/plugins/shared/actions/server/types.ts +++ b/x-pack/platform/plugins/shared/actions/server/types.ts @@ -266,6 +266,7 @@ export interface ResponseSettings { } export interface ConnectorToken extends SavedObjectAttributes { + id?: string; connectorId: string; tokenType: string; token: string; From cadda5897b9b173ef346f6e8dec4733ecad1105e Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Wed, 24 Dec 2025 18:25:40 +0200 Subject: [PATCH 06/49] Make expiresIn optional and add a bunch of helper comments to come back to --- .../src/auth_types/oauth_authorization_code.ts | 1 + .../lib/get_oauth_authorization_code_access_token.ts | 4 ++-- .../shared/actions/server/lib/oauth_state_client.ts | 1 + .../shared/actions/server/lib/request_oauth_token.ts | 2 +- .../shared/actions/server/routes/oauth_callback.ts | 10 ++++++++-- x-pack/platform/plugins/shared/actions/server/types.ts | 1 + 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts index 67493ccc57114..76c6caea4a3ef 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts @@ -86,6 +86,7 @@ export const OAuthAuthorizationCode: AuthTypeSpec = { ): Promise => { // For authorization code flow, tokens are managed separately via callback routes // The getToken() method will retrieve already-stored tokens and auto-refresh if needed + // For this auth spec, getToken() calls getOAuthAuthorizationCodeAccessToken() let token; try { token = await ctx.getToken({ diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts index cd8dfba58ec2d..2ec1a94a0d7f1 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts @@ -33,8 +33,8 @@ interface GetOAuthAuthorizationCodeAccessTokenOpts { } /** - * Get access token for OAuth2 Authorization Code flow - * Automatically refreshes expired tokens using refresh token + * Get an access token for OAuth2 Authorization Code flow + * Automatically refreshes expired tokens using the refresh token */ export const getOAuthAuthorizationCodeAccessToken = async ({ connectorId, diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts index 086c6930db3eb..1e7a4b0fd3214 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts @@ -184,6 +184,7 @@ export class OAuthStateClient { /** * Clean up expired OAuth states (called periodically) */ + // FIXME: call this via Taskmanager scheduled task public async cleanupExpiredStates(): Promise { try { const result = await this.unsecuredSavedObjectsClient.find({ diff --git a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts index 69f63b852c346..4b7ed98aedf7e 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts @@ -16,7 +16,7 @@ import type { AsApiContract } from '../../common'; export interface OAuthTokenResponse { tokenType: string; accessToken: string; - expiresIn: number; + expiresIn?: number; refreshToken?: string; refreshTokenExpiresIn?: number; } diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index 276dbcdb9de9f..59dd029c36469 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -276,6 +276,8 @@ export const oauthCallbackRoute = ( } // Exchange authorization code for tokens + // TODO: couldn't this be either an Opaque token (as below) or a JWT token (requestOAuthJWTToken)? + // depending on the 3rd party's implementation of the token endpoint const tokenResult = await requestOAuthAuthorizationCodeToken( tokenUrl, logger, @@ -301,7 +303,9 @@ export const oauthCallbackRoute = ( }); const now = Date.now(); - const accessTokenExpiresAt = new Date(now + tokenResult.expiresIn * 1000).toISOString(); + // TODO: if no expiresIn, can we set accessTokenExpiresAt to null and handle that? + const expiresIn = tokenResult.expiresIn ? tokenResult.expiresIn : 3600; + const accessTokenExpiresAt = new Date(now + expiresIn * 1000).toISOString(); const refreshTokenExpiresAt = tokenResult.refreshTokenExpiresIn ? new Date(now + tokenResult.refreshTokenExpiresIn * 1000).toISOString() @@ -318,7 +322,7 @@ export const oauthCallbackRoute = ( `Successfully exchanged authorization code for access token for connectorId: ${oauthState.connectorId}` ); - // Create new token record + // Create a new token record await connectorTokenClient.createWithRefreshToken({ connectorId: oauthState.connectorId, accessToken: formattedToken, @@ -333,6 +337,7 @@ export const oauthCallbackRoute = ( // Return success page return res.ok({ + // FIXME: redirect to a page instead! kibana url from state object headers: { 'content-type': 'text/html' }, body: generateOAuthCallbackPage({ title: 'OAuth Authorization Successful', @@ -351,6 +356,7 @@ export const oauthCallbackRoute = ( routeLogger.debug(`OAuth callback error stack: ${err.stack}`); } return res.ok({ + // FIXME: redirect to a page instead? headers: { 'content-type': 'text/html' }, body: generateOAuthCallbackPage({ title: 'OAuth Authorization Failed', diff --git a/x-pack/platform/plugins/shared/actions/server/types.ts b/x-pack/platform/plugins/shared/actions/server/types.ts index 1e23cff7f6dd7..4095885bd3e16 100644 --- a/x-pack/platform/plugins/shared/actions/server/types.ts +++ b/x-pack/platform/plugins/shared/actions/server/types.ts @@ -265,6 +265,7 @@ export interface ResponseSettings { timeout: number; } +// FIXME: remove deprecated approach and use example from DataConnector SO export interface ConnectorToken extends SavedObjectAttributes { id?: string; connectorId: string; From e72ae0e95d66e87e4a79afea67fbeb00d8b3f286 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Fri, 26 Dec 2025 17:33:31 +0200 Subject: [PATCH 07/49] Make expiresIn optional --- .../actions/server/lib/connector_token_client.ts | 13 ++++++++----- .../shared/actions/server/routes/oauth_callback.ts | 6 +++--- .../platform/plugins/shared/actions/server/types.ts | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts index cc009a44236db..a261a9ff6284c 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts @@ -25,14 +25,14 @@ interface ConstructorOptions { interface CreateOptions { connectorId: string; token: string; - expiresAtMillis: string; + expiresAtMillis?: string; tokenType?: string; } export interface UpdateOptions { id: string; token: string; - expiresAtMillis: string; + expiresAtMillis?: string; tokenType?: string; } @@ -216,7 +216,10 @@ export class ConnectorTokenClient { return { hasErrors: true, connectorToken: null }; } - if (isNaN(Date.parse(connectorTokensResult[0].attributes.expiresAt))) { + if ( + connectorTokensResult[0].attributes.expiresAt && + isNaN(Date.parse(connectorTokensResult[0].attributes.expiresAt)) + ) { this.logger.error( `Failed to get connector_token for connectorId "${connectorId}" and tokenType: "${ tokenType ?? 'access_token' @@ -315,7 +318,7 @@ export class ConnectorTokenClient { connectorId: string; accessToken: string; refreshToken?: string; - expiresAtMillis: string; + expiresAtMillis?: string; refreshTokenExpiresAtMillis?: string; tokenType?: string; }): Promise { @@ -364,7 +367,7 @@ export class ConnectorTokenClient { id: string; token: string; refreshToken?: string; - expiresAtMillis: string; + expiresAtMillis?: string; refreshTokenExpiresAtMillis?: string; tokenType?: string; }): Promise { diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index 59dd029c36469..9bf30c984b152 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -303,9 +303,9 @@ export const oauthCallbackRoute = ( }); const now = Date.now(); - // TODO: if no expiresIn, can we set accessTokenExpiresAt to null and handle that? - const expiresIn = tokenResult.expiresIn ? tokenResult.expiresIn : 3600; - const accessTokenExpiresAt = new Date(now + expiresIn * 1000).toISOString(); + const accessTokenExpiresAt = tokenResult.expiresIn + ? new Date(now + tokenResult.expiresIn * 1000).toISOString() + : undefined; const refreshTokenExpiresAt = tokenResult.refreshTokenExpiresIn ? new Date(now + tokenResult.refreshTokenExpiresIn * 1000).toISOString() diff --git a/x-pack/platform/plugins/shared/actions/server/types.ts b/x-pack/platform/plugins/shared/actions/server/types.ts index 4095885bd3e16..75ed8727404e4 100644 --- a/x-pack/platform/plugins/shared/actions/server/types.ts +++ b/x-pack/platform/plugins/shared/actions/server/types.ts @@ -271,7 +271,7 @@ export interface ConnectorToken extends SavedObjectAttributes { connectorId: string; tokenType: string; token: string; - expiresAt: string; + expiresAt?: string; createdAt: string; updatedAt?: string; refreshToken?: string; From 5764ef946a98a592bc6baf243befdd002ec6cd02 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Fri, 26 Dec 2025 18:28:15 +0200 Subject: [PATCH 08/49] Add taskmanager task to cleanup state --- .../server/lib/oauth_state_cleanup_task.ts | 131 ++++++++++++++++++ .../actions/server/lib/oauth_state_client.ts | 3 +- .../plugins/shared/actions/server/plugin.ts | 8 ++ 3 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts new file mode 100644 index 0000000000000..3e2c3e13142bc --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger, CoreSetup } from '@kbn/core/server'; +import type { + TaskManagerSetupContract, + TaskManagerStartContract, + IntervalSchedule, + ConcreteTaskInstance, +} from '@kbn/task-manager-plugin/server'; +import type { ActionsPluginsStart } from '../plugin'; +import { OAuthStateClient } from './oauth_state_client'; + +export const OAUTH_STATE_CLEANUP_TASK_TYPE = 'actions:oauth_state_cleanup'; +export const OAUTH_STATE_CLEANUP_TASK_ID = `Actions-${OAUTH_STATE_CLEANUP_TASK_TYPE}`; +export const OAUTH_STATE_CLEANUP_SCHEDULE: IntervalSchedule = { interval: '1h' }; + +interface TaskState { + runs: number; + last_cleanup_count: number; +} + +const emptyState: TaskState = { + runs: 0, + last_cleanup_count: 0, +}; + +export function initializeOAuthStateCleanupTask( + logger: Logger, + taskManager: TaskManagerSetupContract, + core: CoreSetup +) { + registerOAuthStateCleanupTask(logger, taskManager, core); +} + +export function scheduleOAuthStateCleanupTask( + logger: Logger, + taskManager: TaskManagerStartContract +) { + scheduleTask(logger, taskManager).catch(() => { + // catch to prevent unhandled promise rejection + }); +} + +function registerOAuthStateCleanupTask( + logger: Logger, + taskManager: TaskManagerSetupContract, + core: CoreSetup +) { + taskManager.registerTaskDefinitions({ + [OAUTH_STATE_CLEANUP_TASK_TYPE]: { + title: 'OAuth state cleanup task', + description: 'Periodically removes expired OAuth state objects', + timeout: '1m', + // FIXME: WUT is wrong with the type here?!?! + createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { + return { + run: async () => { + const state = taskInstance.state as TaskState; + + try { + const [coreStart, { encryptedSavedObjects }] = await core.getStartServices(); + + const unsecuredSavedObjectsClient = coreStart.savedObjects.createInternalRepository(); + const encryptedSavedObjectsClient = encryptedSavedObjects.getClient({ + includedHiddenTypes: ['oauth_state'], + }); + const oauthStateClient = new OAuthStateClient({ + encryptedSavedObjectsClient, + unsecuredSavedObjectsClient, + logger: logger.get('oauth_state_cleanup'), + }); + + const cleanupCount = await oauthStateClient.cleanupExpiredStates(); + + logger.debug( + `OAuth state cleanup task completed. Cleaned up ${cleanupCount} expired states.` + ); + + const updatedState: TaskState = { + runs: (state.runs || 0) + 1, + last_cleanup_count: cleanupCount, + }; + + return { + state: updatedState, + schedule: OAUTH_STATE_CLEANUP_SCHEDULE, + }; + } catch (error) { + logger.error( + `OAuth state cleanup task failed: ${ + error instanceof Error ? error.message : String(error) + }` + ); + + return { + state: { + runs: (state.runs || 0) + 1, + last_cleanup_count: 0, + }, + schedule: OAUTH_STATE_CLEANUP_SCHEDULE, + }; + } + }, + }; + }, + }, + }); +} + +async function scheduleTask(logger: Logger, taskManager: TaskManagerStartContract) { + try { + await taskManager.ensureScheduled({ + id: OAUTH_STATE_CLEANUP_TASK_ID, + taskType: OAUTH_STATE_CLEANUP_TASK_TYPE, + state: emptyState, + params: {}, + schedule: OAUTH_STATE_CLEANUP_SCHEDULE, + }); + } catch (e) { + logger.error( + `Error scheduling ${OAUTH_STATE_CLEANUP_TASK_ID}, received ${ + e instanceof Error ? e.message : String(e) + }` + ); + } +} diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts index 1e7a4b0fd3214..baa8b1525d22b 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts @@ -182,9 +182,8 @@ export class OAuthStateClient { } /** - * Clean up expired OAuth states (called periodically) + * Clean up expired OAuth states (called periodically by task manager) */ - // FIXME: call this via Taskmanager scheduled task public async cleanupExpiredStates(): Promise { try { const result = await this.unsecuredSavedObjectsClient.find({ diff --git a/x-pack/platform/plugins/shared/actions/server/plugin.ts b/x-pack/platform/plugins/shared/actions/server/plugin.ts index 8ddd07f7f23d5..20ef9fe3535f4 100644 --- a/x-pack/platform/plugins/shared/actions/server/plugin.ts +++ b/x-pack/platform/plugins/shared/actions/server/plugin.ts @@ -71,6 +71,10 @@ import { getActionsConfigurationUtilities } from './actions_config'; import { defineRoutes } from './routes'; import { initializeActionsTelemetry, scheduleActionsTelemetry } from './usage/task'; +import { + initializeOAuthStateCleanupTask, + scheduleOAuthStateCleanupTask, +} from './lib/oauth_state_cleanup_task'; import { ACTION_SAVED_OBJECT_TYPE, ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, @@ -367,6 +371,9 @@ export class ActionsPlugin }); } + // Initialize OAuth state cleanup task + initializeOAuthStateCleanupTask(this.logger, plugins.taskManager, core); + const subActionFramework = createSubActionConnectorFramework({ actionTypeRegistry, logger: this.logger, @@ -613,6 +620,7 @@ export class ActionsPlugin this.eventLogService!.isEsContextReady() .then(() => { scheduleActionsTelemetry(this.telemetryLogger, plugins.taskManager); + scheduleOAuthStateCleanupTask(this.logger, plugins.taskManager); }) .catch(() => {}); From 5c722877a9433820c7029c62ebf5a2ddd1aeb83e Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Fri, 26 Dec 2025 18:49:02 +0200 Subject: [PATCH 09/49] Update connectors for optional expiresAt --- .../shared/actions/server/lib/get_gcp_oauth_access_token.ts | 5 ++++- .../server/lib/get_oauth_authorization_code_access_token.ts | 2 +- .../server/lib/get_oauth_client_credentials_access_token.ts | 5 ++++- .../shared/actions/server/lib/get_oauth_jwt_access_token.ts | 5 ++++- x-pack/platform/plugins/shared/actions/server/types.ts | 1 - .../server/connector_types/crowdstrike/token_manager.ts | 2 +- .../microsoft_defender_endpoint/o_auth_token_manager.ts | 2 +- 7 files changed, 15 insertions(+), 7 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_gcp_oauth_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_gcp_oauth_access_token.ts index ca2d0de2f0ea5..34ec21f3953cd 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_gcp_oauth_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_gcp_oauth_access_token.ts @@ -40,7 +40,10 @@ export const getGoogleOAuthJwtAccessToken = async ({ } } - if (!connectorToken || Date.parse(connectorToken.expiresAt) <= Date.now()) { + if ( + !connectorToken || + (connectorToken.expiresAt ? Date.parse(connectorToken.expiresAt) <= Date.now() : false) + ) { const requestTokenStart = Date.now(); // Request access token with service account credentials file diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts index 2ec1a94a0d7f1..73d60e2746100 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts @@ -73,7 +73,7 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ // Check if access token is still valid const now = Date.now(); - const expiresAt = Date.parse(connectorToken.expiresAt); + const expiresAt = connectorToken.expiresAt ? Date.parse(connectorToken.expiresAt) : Infinity; if (expiresAt > now) { // Token still valid diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts index 8d48e7560c791..8452b7ef9d53e 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts @@ -61,7 +61,10 @@ export const getOAuthClientCredentialsAccessToken = async ({ hasErrors = errors; } - if (connectorToken === null || Date.parse(connectorToken.expiresAt) <= Date.now()) { + if ( + connectorToken === null || + (connectorToken.expiresAt ? Date.parse(connectorToken.expiresAt) <= Date.now() : false) + ) { // Save the time before requesting token so we can use it to calculate expiration const requestTokenStart = Date.now(); diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts index 06791ac8543a2..20f0b21933f27 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts @@ -63,7 +63,10 @@ export const getOAuthJwtAccessToken = async ({ hasErrors = errors; } - if (connectorToken === null || Date.parse(connectorToken.expiresAt) <= Date.now()) { + if ( + connectorToken === null || + (connectorToken.expiresAt ? Date.parse(connectorToken.expiresAt) <= Date.now() : false) + ) { // generate a new assertion const assertion = createJWTAssertion(logger, privateKey, privateKeyPassword, { audience: clientId, diff --git a/x-pack/platform/plugins/shared/actions/server/types.ts b/x-pack/platform/plugins/shared/actions/server/types.ts index 75ed8727404e4..df8959716192c 100644 --- a/x-pack/platform/plugins/shared/actions/server/types.ts +++ b/x-pack/platform/plugins/shared/actions/server/types.ts @@ -265,7 +265,6 @@ export interface ResponseSettings { timeout: number; } -// FIXME: remove deprecated approach and use example from DataConnector SO export interface ConnectorToken extends SavedObjectAttributes { id?: string; connectorId: string; diff --git a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.ts b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.ts index ff21eee662a22..8eb76f3f70363 100644 --- a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.ts +++ b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.ts @@ -45,7 +45,7 @@ export class CrowdStrikeTokenManager { const now = new Date(); now.setSeconds(now.getSeconds() - 5); // 5-second safety margin - const isExpired = token.expiresAt < now.toISOString(); + const isExpired = token.expiresAt ? token.expiresAt < now.toISOString() : false; if (isExpired) { this.logger.debug(`Cached access token expired at [${token.expiresAt}]`); diff --git a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/o_auth_token_manager.ts b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/o_auth_token_manager.ts index ef6159995cf0a..3b8d80d20bfe4 100644 --- a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/o_auth_token_manager.ts +++ b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/o_auth_token_manager.ts @@ -47,7 +47,7 @@ export class OAuthTokenManager { const now = new Date(); now.setSeconds(now.getSeconds() - 5); // Allows for a threshold of -5s before considering the token expired - const isExpired = token.expiresAt < now.toISOString(); + const isExpired = token.expiresAt ? token.expiresAt < now.toISOString() : false; if (isExpired) { this.logger.debug(`Cached access token expired at [${token.expiresAt}]`); From 3c861630adfdb9d2c03971402df4e1c716369b5e Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Mon, 29 Dec 2025 17:40:56 +0100 Subject: [PATCH 10/49] Increase task frequency --- .../shared/actions/server/lib/oauth_state_cleanup_task.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts index 3e2c3e13142bc..5c5d84784aa51 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts @@ -17,7 +17,7 @@ import { OAuthStateClient } from './oauth_state_client'; export const OAUTH_STATE_CLEANUP_TASK_TYPE = 'actions:oauth_state_cleanup'; export const OAUTH_STATE_CLEANUP_TASK_ID = `Actions-${OAUTH_STATE_CLEANUP_TASK_TYPE}`; -export const OAUTH_STATE_CLEANUP_SCHEDULE: IntervalSchedule = { interval: '1h' }; +export const OAUTH_STATE_CLEANUP_SCHEDULE: IntervalSchedule = { interval: '30m' }; interface TaskState { runs: number; From 41734d24eb1728259e5f369d61641b25632420c0 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Mon, 29 Dec 2025 18:27:47 +0100 Subject: [PATCH 11/49] Add rate limiter --- .../plugins/shared/actions/server/config.ts | 13 + .../server/lib/oauth_rate_limiter.test.ts | 230 ++++++++++++++++++ .../actions/server/lib/oauth_rate_limiter.ts | 60 +++++ .../plugins/shared/actions/server/plugin.ts | 7 + .../shared/actions/server/routes/index.ts | 25 +- .../actions/server/routes/oauth_authorize.ts | 28 ++- .../actions/server/routes/oauth_callback.ts | 35 ++- 7 files changed, 382 insertions(+), 16 deletions(-) create mode 100644 x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.test.ts create mode 100644 x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.ts diff --git a/x-pack/platform/plugins/shared/actions/server/config.ts b/x-pack/platform/plugins/shared/actions/server/config.ts index 4e263eb5c9730..4bc6070cbf407 100644 --- a/x-pack/platform/plugins/shared/actions/server/config.ts +++ b/x-pack/platform/plugins/shared/actions/server/config.ts @@ -73,6 +73,17 @@ const rateLimiterSchema = schema.recordOf( }) ); +const oAuthRateLimitSchema = schema.object({ + authorize: schema.object({ + lookbackWindow: schema.string({ defaultValue: '1h', validate: validateDuration }), + limit: schema.number({ defaultValue: 10, min: 1, max: 1000 }), + }), + callback: schema.object({ + lookbackWindow: schema.string({ defaultValue: '1h', validate: validateDuration }), + limit: schema.number({ defaultValue: 50, min: 1, max: 1000 }), + }), +}); + export const configSchema = schema.object({ allowedHosts: schema.arrayOf( schema.oneOf([schema.string({ hostname: true }), schema.literal(AllowedHosts.Any)]), @@ -200,11 +211,13 @@ export const configSchema = schema.object({ }) ), rateLimiter: schema.maybe(rateLimiterSchema), + oAuthRateLimit: oAuthRateLimitSchema, }); export type ActionsConfig = TypeOf; export type EnabledConnectorTypes = TypeOf; export type ConnectorRateLimiterConfig = TypeOf; +export type OAuthRateLimiterConfig = TypeOf; // It would be nicer to add the proxyBypassHosts / proxyOnlyHosts restriction on // simultaneous usage in the config validator directly, but there's no good way to express diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.test.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.test.ts new file mode 100644 index 0000000000000..48907adf93287 --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.test.ts @@ -0,0 +1,230 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { OAuthRateLimiter } from './oauth_rate_limiter'; + +const DEFAULT_CONFIG = { + authorize: { limit: 10, lookbackWindow: '1h' }, + callback: { limit: 50, lookbackWindow: '1h' }, +}; + +describe('OAuthRateLimiter', () => { + beforeEach(() => { + jest.useFakeTimers(); + jest.setSystemTime(new Date('2025-06-24T15:30:00.000Z')); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + describe('log', () => { + it('should log OAuth requests for a user and endpoint', () => { + const rateLimiter = new OAuthRateLimiter({ config: DEFAULT_CONFIG }); + + rateLimiter.log('user1', 'authorize'); + jest.advanceTimersByTime(1000); + rateLimiter.log('user1', 'authorize'); + jest.advanceTimersByTime(1000); + rateLimiter.log('user1', 'authorize'); + + expect(rateLimiter.getLogs('user1', 'authorize')).toEqual([ + 1750779000000, 1750779001000, 1750779002000, + ]); + }); + + it('should track multiple users independently', () => { + const rateLimiter = new OAuthRateLimiter({ config: DEFAULT_CONFIG }); + + rateLimiter.log('user1', 'authorize'); + jest.advanceTimersByTime(1000); + rateLimiter.log('user2', 'authorize'); + jest.advanceTimersByTime(1000); + rateLimiter.log('user1', 'authorize'); + + expect(rateLimiter.getLogs('user1', 'authorize')).toEqual([1750779000000, 1750779002000]); + expect(rateLimiter.getLogs('user2', 'authorize')).toEqual([1750779001000]); + }); + + it('should track multiple endpoints independently for the same user', () => { + const rateLimiter = new OAuthRateLimiter({ config: DEFAULT_CONFIG }); + + rateLimiter.log('user1', 'authorize'); + jest.advanceTimersByTime(1000); + rateLimiter.log('user1', 'callback'); + jest.advanceTimersByTime(1000); + rateLimiter.log('user1', 'authorize'); + + expect(rateLimiter.getLogs('user1', 'authorize')).toEqual([1750779000000, 1750779002000]); + expect(rateLimiter.getLogs('user1', 'callback')).toEqual([1750779001000]); + }); + }); + + describe('isRateLimited', () => { + it('should return false when request count is below limit', () => { + const rateLimiter = new OAuthRateLimiter({ config: DEFAULT_CONFIG }); + + for (let i = 0; i < 5; i++) { + rateLimiter.log('user1', 'authorize'); + jest.advanceTimersByTime(1000); + } + + expect(rateLimiter.isRateLimited('user1', 'authorize')).toBe(false); + }); + + it('should return true when request count reaches or exceeds limit', () => { + const rateLimiter = new OAuthRateLimiter({ config: DEFAULT_CONFIG }); + + for (let i = 0; i < 10; i++) { + rateLimiter.log('user1', 'authorize'); + jest.advanceTimersByTime(1000); + } + + for (let i = 0; i < 15; i++) { + rateLimiter.log('user2', 'authorize'); + jest.advanceTimersByTime(1000); + } + + expect(rateLimiter.isRateLimited('user1', 'authorize')).toBe(true); + expect(rateLimiter.isRateLimited('user2', 'authorize')).toBe(true); + }); + + it('should respect different limits for different endpoints', () => { + const config = { + authorize: { limit: 5, lookbackWindow: '1h' }, + callback: { limit: 20, lookbackWindow: '1h' }, + }; + const rateLimiter = new OAuthRateLimiter({ config }); + + // Authorize endpoint - hit limit + for (let i = 0; i < 5; i++) { + rateLimiter.log('user1', 'authorize'); + jest.advanceTimersByTime(1000); + } + + // Callback endpoint - under limit + for (let i = 0; i < 10; i++) { + rateLimiter.log('user1', 'callback'); + jest.advanceTimersByTime(1000); + } + + expect(rateLimiter.isRateLimited('user1', 'authorize')).toBe(true); + expect(rateLimiter.isRateLimited('user1', 'callback')).toBe(false); + }); + + it('should rate limit users independently', () => { + const config = { + authorize: { limit: 5, lookbackWindow: '1h' }, + callback: { limit: 50, lookbackWindow: '1h' }, + }; + const rateLimiter = new OAuthRateLimiter({ config }); + + // User1 hits limit + for (let i = 0; i < 5; i++) { + rateLimiter.log('user1', 'authorize'); + jest.advanceTimersByTime(1000); + } + + // User2 under limit + for (let i = 0; i < 3; i++) { + rateLimiter.log('user2', 'authorize'); + jest.advanceTimersByTime(1000); + } + + expect(rateLimiter.isRateLimited('user1', 'authorize')).toBe(true); + expect(rateLimiter.isRateLimited('user2', 'authorize')).toBe(false); + }); + }); + + describe('lookback window cleanup', () => { + it('should cleanup old logs outside lookback window', () => { + const config = { + authorize: { limit: 100, lookbackWindow: '10s' }, + callback: { limit: 50, lookbackWindow: '1h' }, + }; + const rateLimiter = new OAuthRateLimiter({ config }); + + // Log 16 requests over 16 seconds + for (let i = 0; i <= 15; i++) { + rateLimiter.log('user1', 'authorize'); + jest.advanceTimersByTime(1000); + } + + // Before cleanup, all logs present + expect(rateLimiter.getLogs('user1', 'authorize')).toHaveLength(16); + + // Trigger cleanup via isRateLimited + rateLimiter.isRateLimited('user1', 'authorize'); + + // After cleanup, only the last 10 seconds remain + expect(rateLimiter.getLogs('user1', 'authorize')).toHaveLength(10); + expect(rateLimiter.getLogs('user1', 'authorize')).toEqual([ + 1750779006000, 1750779007000, 1750779008000, 1750779009000, 1750779010000, 1750779011000, + 1750779012000, 1750779013000, 1750779014000, 1750779015000, + ]); + }); + + it('should allow requests after lookback window expires', () => { + const config = { + authorize: { limit: 5, lookbackWindow: '10s' }, + callback: { limit: 50, lookbackWindow: '1h' }, + }; + const rateLimiter = new OAuthRateLimiter({ config }); + + // Hit the limit + for (let i = 0; i < 5; i++) { + rateLimiter.log('user1', 'authorize'); + jest.advanceTimersByTime(1000); + } + + expect(rateLimiter.isRateLimited('user1', 'authorize')).toBe(true); + + // Advance time beyond lookback window + jest.advanceTimersByTime(11000); + + // Should no longer be rate limited + expect(rateLimiter.isRateLimited('user1', 'authorize')).toBe(false); + }); + }); + + describe('anonymous users', () => { + it('should handle anonymous user requests', () => { + const rateLimiter = new OAuthRateLimiter({ config: DEFAULT_CONFIG }); + + for (let i = 0; i < 5; i++) { + rateLimiter.log('anonymous', 'authorize'); + jest.advanceTimersByTime(1000); + } + + expect(rateLimiter.isRateLimited('anonymous', 'authorize')).toBe(false); + expect(rateLimiter.getLogs('anonymous', 'authorize')).toHaveLength(5); + }); + + it('should rate limit anonymous users independently from authenticated users', () => { + const config = { + authorize: { limit: 5, lookbackWindow: '1h' }, + callback: { limit: 50, lookbackWindow: '1h' }, + }; + const rateLimiter = new OAuthRateLimiter({ config }); + + // Anonymous hits limit + for (let i = 0; i < 5; i++) { + rateLimiter.log('anonymous', 'authorize'); + jest.advanceTimersByTime(1000); + } + + // Authenticated user under limit + for (let i = 0; i < 3; i++) { + rateLimiter.log('user1', 'authorize'); + jest.advanceTimersByTime(1000); + } + + expect(rateLimiter.isRateLimited('anonymous', 'authorize')).toBe(true); + expect(rateLimiter.isRateLimited('user1', 'authorize')).toBe(false); + }); + }); +}); diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.ts new file mode 100644 index 0000000000000..d2bee379e995d --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { OAuthRateLimiterConfig } from '../config'; +import { parseDuration } from './parse_date'; + +type OAuthEndpoint = 'authorize' | 'callback'; + +export class OAuthRateLimiter { + private logsByUserAndEndpoint: Map; + private readonly config: OAuthRateLimiterConfig; + + constructor({ config }: { config: OAuthRateLimiterConfig }) { + this.logsByUserAndEndpoint = new Map(); + this.config = config; + } + + log(username: string, endpoint: OAuthEndpoint) { + const key = this.createKey(username, endpoint); + const now = Date.now(); + + if (!this.logsByUserAndEndpoint.has(key)) { + this.logsByUserAndEndpoint.set(key, []); + } + + this.logsByUserAndEndpoint.get(key)!.push(now); + } + + isRateLimited(username: string, endpoint: OAuthEndpoint): boolean { + const key = this.createKey(username, endpoint); + this.cleanupOldLogs(key, endpoint); + + const count = this.getLogs(username, endpoint).length; + const limit = this.config[endpoint].limit; + + return count >= limit; + } + + getLogs(username: string, endpoint: OAuthEndpoint): number[] { + const key = this.createKey(username, endpoint); + return this.logsByUserAndEndpoint.get(key) || []; + } + + private cleanupOldLogs(key: string, endpoint: OAuthEndpoint) { + const endpointConfig = this.config[endpoint]; + const now = Date.now(); + const cutoff = now - parseDuration(endpointConfig.lookbackWindow); + + const filtered = this.logsByUserAndEndpoint.get(key)?.filter((ts) => ts >= cutoff) || []; + this.logsByUserAndEndpoint.set(key, filtered); + } + + private createKey(username: string, endpoint: OAuthEndpoint): string { + return `${username}:${endpoint}`; + } +} diff --git a/x-pack/platform/plugins/shared/actions/server/plugin.ts b/x-pack/platform/plugins/shared/actions/server/plugin.ts index 20ef9fe3535f4..8c0fcfea80398 100644 --- a/x-pack/platform/plugins/shared/actions/server/plugin.ts +++ b/x-pack/platform/plugins/shared/actions/server/plugin.ts @@ -109,6 +109,7 @@ import { createBulkUnsecuredExecutionEnqueuerFunction } from './create_unsecured import { createSystemConnectors } from './create_system_actions'; import { ConnectorUsageReportingTask } from './usage/connector_usage_reporting_task'; import { ConnectorRateLimiter } from './lib/connector_rate_limiter'; +import { OAuthRateLimiter } from './lib/oauth_rate_limiter'; import type { GetAxiosInstanceWithAuthFnOpts } from './lib/get_axios_instance'; import { getAxiosInstanceWithAuth } from './lib/get_axios_instance'; @@ -380,6 +381,11 @@ export class ActionsPlugin actionsConfigUtils, }); + // Initialize OAuth rate limiter + const oauthRateLimiter = new OAuthRateLimiter({ + config: this.actionsConfig.oAuthRateLimit, + }); + // Routes defineRoutes({ router: core.http.createRouter(), @@ -388,6 +394,7 @@ export class ActionsPlugin usageCounter: this.usageCounter, logger: this.logger, core, + oauthRateLimiter, getEncryptedSavedObjects: async () => { const [, { encryptedSavedObjects }] = await core.getStartServices(); return encryptedSavedObjects; diff --git a/x-pack/platform/plugins/shared/actions/server/routes/index.ts b/x-pack/platform/plugins/shared/actions/server/routes/index.ts index 00c4544c8ce5e..ddb9bebe57cc5 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/index.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/index.ts @@ -28,6 +28,7 @@ import { getGlobalExecutionLogRoute } from './get_global_execution_logs'; import { getGlobalExecutionKPIRoute } from './get_global_execution_kpi'; import type { ActionsPluginsStart } from '../plugin'; +import type { OAuthRateLimiter } from '../lib/oauth_rate_limiter'; export interface RouteOptions { router: IRouter; @@ -37,10 +38,19 @@ export interface RouteOptions { getEncryptedSavedObjects?: () => Promise; logger: Logger; core: CoreSetup; + oauthRateLimiter: OAuthRateLimiter; } export function defineRoutes(opts: RouteOptions) { - const { router, licenseState, actionsConfigUtils, getEncryptedSavedObjects, logger, core } = opts; + const { + router, + licenseState, + actionsConfigUtils, + getEncryptedSavedObjects, + logger, + core, + oauthRateLimiter, + } = opts; createConnectorRoute(router, licenseState); deleteConnectorRoute(router, licenseState); @@ -56,12 +66,19 @@ export function defineRoutes(opts: RouteOptions) { oauthAuthorizeRoute( router, licenseState, - actionsConfigUtils, logger, core, - getEncryptedSavedObjects + getEncryptedSavedObjects, + oauthRateLimiter + ); + oauthCallbackRoute( + router, + licenseState, + actionsConfigUtils, + logger, + getEncryptedSavedObjects, + oauthRateLimiter ); - oauthCallbackRoute(router, licenseState, actionsConfigUtils, logger, getEncryptedSavedObjects); getAllConnectorsIncludingSystemRoute(router, licenseState); listTypesWithSystemRoute(router, licenseState); } diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts index 634dd47f4b255..bb08b5ecab347 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts @@ -13,11 +13,11 @@ import type { ILicenseState } from '../lib'; import { INTERNAL_BASE_ACTION_API_PATH } from '../../common'; import type { ActionsRequestHandlerContext } from '../types'; import { verifyAccessAndContext } from './verify_access_and_context'; -import type { ActionsConfigurationUtilities } from '../actions_config'; import { DEFAULT_ACTION_ROUTE_SECURITY } from './constants'; import { OAuthStateClient } from '../lib/oauth_state_client'; import { OAuthAuthorizationService } from '../lib/oauth_authorization_service'; import type { ActionsPluginsStart } from '../plugin'; +import type { OAuthRateLimiter } from '../lib/oauth_rate_limiter'; const paramsSchema = schema.object({ connectorId: schema.string(), @@ -32,10 +32,10 @@ export type OAuthAuthorizeParams = TypeOf; export const oauthAuthorizeRoute = ( router: IRouter, licenseState: ILicenseState, - configurationUtilities: ActionsConfigurationUtilities, logger: Logger, coreSetup: CoreSetup, - getEncryptedSavedObjects?: () => Promise + getEncryptedSavedObjects: (() => Promise) | undefined, + oauthRateLimiter: OAuthRateLimiter ) => { router.post( { @@ -54,9 +54,29 @@ export const oauthAuthorizeRoute = ( try { const core = await context.core; - const actionsClient = (await context.actions).getActionsClient(); const routeLogger = logger.get('oauth_authorize'); + // Check rate limit + const currentUser = core.security.authc.getCurrentUser(); + const username = currentUser?.username || 'anonymous'; + + if (oauthRateLimiter.isRateLimited(username, 'authorize')) { + routeLogger.warn( + `OAuth authorize rate limit exceeded for user: ${username}, connector: ${connectorId}` + ); + return res.customError({ + statusCode: 429, + body: { + message: 'Too many authorization attempts. Please try again later.', + }, + }); + } + + // Log the request + oauthRateLimiter.log(username, 'authorize'); + + const actionsClient = (await context.actions).getActionsClient(); + // Get encrypted saved objects client if (!getEncryptedSavedObjects) { throw new Error('EncryptedSavedObjects plugin not available'); diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index 9bf30c984b152..40d8451689446 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -5,7 +5,6 @@ * 2.0. */ -import type { TypeOf } from '@kbn/config-schema'; import { schema } from '@kbn/config-schema'; import type { IRouter, Logger } from '@kbn/core/server'; import type { EncryptedSavedObjectsPluginStart } from '@kbn/encrypted-saved-objects-plugin/server'; @@ -18,6 +17,7 @@ import { verifyAccessAndContext } from './verify_access_and_context'; import { OAuthStateClient } from '../lib/oauth_state_client'; import { requestOAuthAuthorizationCodeToken } from '../lib/request_oauth_authorization_code_token'; import { ConnectorTokenClient } from '../lib/connector_token_client'; +import type { OAuthRateLimiter } from '../lib/oauth_rate_limiter'; const querySchema = schema.object({ code: schema.maybe(schema.string()), @@ -27,8 +27,6 @@ const querySchema = schema.object({ session_state: schema.maybe(schema.string()), // Microsoft OAuth includes this }); -export type OAuthCallbackQuery = TypeOf; - interface OAuthConnectorSecrets { clientId?: string; clientSecret?: string; @@ -169,7 +167,8 @@ export const oauthCallbackRoute = ( licenseState: ILicenseState, configurationUtilities: ActionsConfigurationUtilities, logger: Logger, - getEncryptedSavedObjects?: () => Promise + getEncryptedSavedObjects: (() => Promise) | undefined, + oauthRateLimiter: OAuthRateLimiter ) => { router.get( { @@ -188,6 +187,30 @@ export const oauthCallbackRoute = ( verifyAccessAndContext(licenseState, async function (context, req, res) { const { code, state: stateParam, error, error_description: errorDescription } = req.query; + const core = await context.core; + const routeLogger = logger.get('oauth_callback'); + + // Check rate limit + const currentUser = core.security.authc.getCurrentUser(); + const username = currentUser?.username || 'anonymous'; + + if (oauthRateLimiter.isRateLimited(username, 'callback')) { + routeLogger.warn(`OAuth callback rate limit exceeded for user: ${username}`); + return res.ok({ + headers: { 'content-type': 'text/html' }, + body: generateOAuthCallbackPage({ + title: 'OAuth Authorization Failed', + heading: 'Too Many Requests', + message: 'You have made too many authorization attempts.', + details: 'Please wait before trying again.', + isSuccess: false, + }), + }); + } + + // Log the request + oauthRateLimiter.log(username, 'callback'); + // Handle OAuth errors or missing parameters if (error || !code || !stateParam) { const errorMessage = error || 'Missing required OAuth parameters (code or state)'; @@ -208,9 +231,6 @@ export const oauthCallbackRoute = ( } try { - const core = await context.core; - const routeLogger = logger.get('oauth_callback'); - // Get encrypted saved objects client if (!getEncryptedSavedObjects) { throw new Error('EncryptedSavedObjects plugin not available'); @@ -349,7 +369,6 @@ export const oauthCallbackRoute = ( }), }); } catch (err) { - const routeLogger = logger.get('oauth_callback'); const errorMessage = err instanceof Error ? err.message : String(err); routeLogger.error(`OAuth callback failed: ${errorMessage}`); if (err instanceof Error && err.stack) { From 0300b1a986228113be553c031529a382d4de9b22 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 30 Dec 2025 11:04:04 +0100 Subject: [PATCH 12/49] Fixes --- .../server/actions_client/actions_client.ts | 5 +++-- .../actions/server/lib/connector_token_client.ts | 16 ++-------------- .../get_oauth_authorization_code_access_token.ts | 6 +++--- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts b/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts index 96c2926cfb271..b69c83e5454be 100644 --- a/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.ts @@ -58,6 +58,7 @@ import type { ActionsAuthorization } from '../authorization/actions_authorizatio import { connectorAuditEvent, ConnectorAuditAction } from '../lib/audit_events'; import type { ActionsConfigurationUtilities } from '../actions_config'; import type { + OAuthAuthorizationCodeParams, OAuthClientCredentialsParams, OAuthJwtParams, OAuthParams, @@ -419,7 +420,7 @@ export class ActionsClient { throw Boom.badRequest(`Failed to retrieve access token`); } } else if (type === 'authorization_code') { - const tokenOpts = options as any; // Will add proper typing in route schema + const tokenOpts = options as OAuthAuthorizationCodeParams; try { accessToken = await getOAuthAuthorizationCodeAccessToken({ connectorId: tokenOpts.connectorId, @@ -429,7 +430,7 @@ export class ActionsClient { config: tokenOpts.config as GetOAuthAuthorizationCodeConfig, secrets: tokenOpts.secrets as GetOAuthAuthorizationCodeSecrets, }, - connectorTokenClient: this.connectorTokenClient, + connectorTokenClient: this.context.connectorTokenClient, scope: tokenOpts.scope, }); diff --git a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts index a261a9ff6284c..44c62544d1597 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts @@ -40,10 +40,11 @@ interface UpdateOrReplaceOptions { connectorId: string; token: ConnectorToken | null; newToken: string; - expiresInSec: number; + expiresInSec?: number; tokenRequestDate: number; deleteExisting: boolean; } + export class ConnectorTokenClient { private readonly logger: Logger; private readonly unsecuredSavedObjectsClient: SavedObjectsClientContract; @@ -424,17 +425,4 @@ export class ConnectorTokenClient { throw err; } } - - /** - * Get refresh token for a connector - */ - public async getRefreshToken({ connectorId }: { connectorId: string }): Promise { - const { connectorToken } = await this.get({ connectorId, tokenType: 'access_token' }); - - if (!connectorToken?.refreshToken) { - return null; - } - - return connectorToken.refreshToken; - } } diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts index 73d60e2746100..3cc2d69825c33 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts @@ -120,9 +120,9 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ const newRefreshToken = tokenResult.refreshToken || connectorToken.refreshToken; // Calculate expiration times - const accessTokenExpiresAt = new Date( - requestTokenStart + tokenResult.expiresIn * 1000 - ).toISOString(); + const accessTokenExpiresAt = tokenResult.expiresIn + ? new Date(requestTokenStart + tokenResult.expiresIn * 1000).toISOString() + : undefined; const refreshTokenExpiresAt = tokenResult.refreshTokenExpiresIn ? new Date(requestTokenStart + tokenResult.refreshTokenExpiresIn * 1000).toISOString() From ff8cdce13775a151d4770446c5e5497615144d5f Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 30 Dec 2025 12:22:43 +0100 Subject: [PATCH 13/49] Redirect to success page --- .../actions/server/lib/oauth_state_client.ts | 4 ++++ .../actions/server/routes/oauth_authorize.ts | 4 ++++ .../actions/server/routes/oauth_callback.ts | 19 ++++++------------- .../schemas/raw_oauth_state/v1.ts | 1 + 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts index baa8b1525d22b..b24a694478a78 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts @@ -22,6 +22,7 @@ export interface OAuthState { redirectUri: string; authorizationUrl: string; scope?: string; + kibanaReturnUrl: string; createdAt: string; expiresAt: string; createdBy?: string; @@ -38,6 +39,7 @@ interface CreateStateOptions { redirectUri: string; authorizationUrl: string; scope?: string; + kibanaReturnUrl: string; createdBy?: string; } @@ -78,6 +80,7 @@ export class OAuthStateClient { redirectUri, authorizationUrl, scope, + kibanaReturnUrl, createdBy, }: CreateStateOptions): Promise<{ state: OAuthState; @@ -101,6 +104,7 @@ export class OAuthStateClient { redirectUri, authorizationUrl, scope, + kibanaReturnUrl, createdAt: now.toISOString(), expiresAt: expiresAt.toISOString(), createdBy, diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts index bb08b5ecab347..c8ee5a0d01175 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts @@ -114,6 +114,9 @@ export const oauthAuthorizeRoute = ( // Get redirect URI const redirectUri = oauthService.getRedirectUri(); + // Build return URL for post-OAuth redirect + const kibanaReturnUrl = `${kibanaUrl}/app/management/insightsAndAlerting/triggersActionsConnectors/connectors`; + // Create OAuth state with PKCE const oauthStateClient = new OAuthStateClient({ encryptedSavedObjectsClient, @@ -128,6 +131,7 @@ export const oauthAuthorizeRoute = ( redirectUri, authorizationUrl: oauthConfig.authorizationUrl, scope: oauthConfig.scope, + kibanaReturnUrl, }); // Build authorization URL diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index 40d8451689446..089602293ad53 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -355,18 +355,12 @@ export const oauthCallbackRoute = ( // Clean up state await oauthStateClient.delete(oauthState.id!); - // Return success page - return res.ok({ - // FIXME: redirect to a page instead! kibana url from state object - headers: { 'content-type': 'text/html' }, - body: generateOAuthCallbackPage({ - title: 'OAuth Authorization Successful', - heading: 'Authorization Successful', - message: 'You have successfully authorized the connector.', - details: 'You can now close this window and return to Kibana.', - isSuccess: true, - autoClose: true, - }), + // Redirect to Kibana + const returnUrl = new URL(oauthState.kibanaReturnUrl); + return res.redirected({ + headers: { + location: returnUrl.toString(), + }, }); } catch (err) { const errorMessage = err instanceof Error ? err.message : String(err); @@ -375,7 +369,6 @@ export const oauthCallbackRoute = ( routeLogger.debug(`OAuth callback error stack: ${err.stack}`); } return res.ok({ - // FIXME: redirect to a page instead? headers: { 'content-type': 'text/html' }, body: generateOAuthCallbackPage({ title: 'OAuth Authorization Failed', diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts index e3acd0cff6c55..78a8de8b31ea1 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts @@ -14,6 +14,7 @@ export const rawOAuthStateSchema = schema.object({ redirectUri: schema.string(), authorizationUrl: schema.string(), scope: schema.maybe(schema.string()), + kibanaReturnUrl: schema.string(), // in case of OAuth success, redirect to this URL createdAt: schema.string(), expiresAt: schema.string(), createdBy: schema.maybe(schema.string()), From 3c77bcd73d4fbed95046814cb3bb8822991703a8 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 30 Dec 2025 12:53:37 +0100 Subject: [PATCH 14/49] Use v2 schema --- .../actions/server/saved_objects/mappings.ts | 3 +++ .../connector_token_model_versions.ts | 12 ++++++++++- .../schemas/raw_connector_token/index.ts | 1 + .../schemas/raw_connector_token/v1.ts | 2 -- .../schemas/raw_connector_token/v2.ts | 20 +++++++++++++++++++ 5 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v2.ts diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/mappings.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/mappings.ts index 0cd027f431cf4..d23836ef00487 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/mappings.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/mappings.ts @@ -132,5 +132,8 @@ export const oauthStateMappings: SavedObjectsTypeMappingDefinition = { // createdBy: { // type: 'keyword', // }, + // kibanaReturnUrl: { + // type: 'keyword', + // }, }, }; diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/connector_token_model_versions.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/connector_token_model_versions.ts index 458d4ade5b46b..267f9c8138c99 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/connector_token_model_versions.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/model_versions/connector_token_model_versions.ts @@ -6,7 +6,10 @@ */ import type { SavedObjectsModelVersionMap } from '@kbn/core-saved-objects-server'; -import { rawConnectorTokenSchemaV1 } from '../schemas/raw_connector_token'; +import { + rawConnectorTokenSchemaV1, + rawConnectorTokenSchemaV2, +} from '../schemas/raw_connector_token'; export const connectorTokenModelVersions: SavedObjectsModelVersionMap = { '1': { @@ -16,4 +19,11 @@ export const connectorTokenModelVersions: SavedObjectsModelVersionMap = { create: rawConnectorTokenSchemaV1, }, }, + '2': { + changes: [], // backwards-compatible schema evolution + schemas: { + forwardCompatibility: rawConnectorTokenSchemaV2.extends({}, { unknowns: 'ignore' }), + create: rawConnectorTokenSchemaV2, + }, + }, }; diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/index.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/index.ts index 66d20c740f8d2..5942efa16e1c5 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/index.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/index.ts @@ -6,3 +6,4 @@ */ export { rawConnectorTokenSchema as rawConnectorTokenSchemaV1 } from './v1'; +export { rawConnectorTokenSchema as rawConnectorTokenSchemaV2 } from './v2'; diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v1.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v1.ts index 21f80e8edc3a8..be91cf266b5bc 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v1.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v1.ts @@ -14,6 +14,4 @@ export const rawConnectorTokenSchema = schema.object({ token: schema.string(), tokenType: schema.string(), updatedAt: schema.string(), - refreshToken: schema.maybe(schema.string()), - refreshTokenExpiresAt: schema.maybe(schema.string()), }); diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v2.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v2.ts new file mode 100644 index 0000000000000..7f02ec9477bbc --- /dev/null +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v2.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const rawConnectorTokenSchema = schema.object({ + createdAt: schema.string(), + connectorId: schema.string(), + expiresAt: schema.maybe(schema.string()), // turned into an optional field + token: schema.string(), + tokenType: schema.string(), + updatedAt: schema.string(), + // added optional fields + refreshToken: schema.maybe(schema.string()), + refreshTokenExpiresAt: schema.maybe(schema.string()), +}); From 2fbf1de9267215ed57b95cc5cae02cf5940c24e0 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 30 Dec 2025 17:41:09 +0100 Subject: [PATCH 15/49] Normalize bearer -> Bearer, add redirectUri to connector config and use that as callback instead of kibana (if present) --- .../auth_types/oauth_authorization_code.ts | 2 ++ .../src/auth_types/translations.ts | 4 +++ .../src/specs/notion/notion.ts | 10 ++++++- ...t_oauth_authorization_code_access_token.ts | 6 +++- ...t_oauth_client_credentials_access_token.ts | 6 +++- .../server/lib/get_oauth_jwt_access_token.ts | 6 +++- .../server/lib/oauth_authorization_service.ts | 23 +++++++++++++-- .../request_oauth_authorization_code_token.ts | 3 +- .../server/lib/request_oauth_refresh_token.ts | 3 +- .../actions/server/lib/request_oauth_token.ts | 29 ++++++++++++++----- .../actions/server/routes/oauth_authorize.ts | 6 +--- .../actions/server/routes/oauth_callback.ts | 6 +++- 12 files changed, 81 insertions(+), 23 deletions(-) diff --git a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts index 76c6caea4a3ef..b8455cc93924c 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts @@ -25,6 +25,8 @@ const authSchema = z .string() .min(1, { message: i18n.OAUTH_CLIENT_SECRET_REQUIRED_MESSAGE }) .meta({ label: i18n.OAUTH_CLIENT_SECRET_LABEL, sensitive: true }), + // when using z.url() it doesn't allow for empty urls even if it's an optional field + redirectUri: z.string().meta({ label: i18n.OAUTH_REDIRECT_URI_LABEL }).optional(), }) .meta({ label: i18n.OAUTH_AUTHORIZATION_CODE_LABEL }); diff --git a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts index c2975aea9ad5f..cb4e07634ed17 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts @@ -131,6 +131,10 @@ export const OAUTH_AUTHORIZATION_URL_LABEL = i18n.translate( } ); +export const OAUTH_REDIRECT_URI_LABEL = i18n.translate('connectorSpecs.oauthRedirectURI.label', { + defaultMessage: 'Redirect URI', +}); + export const CRT_AUTH_LABEL = i18n.translate('connectorSpecs.crt.label', { defaultMessage: 'SSL CRT and Key authentication', }); diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts index bccee2df15f1b..d054ec7d3c636 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts @@ -22,7 +22,15 @@ export const NotionConnector: ConnectorSpec = { }, auth: { - types: ['bearer'], + types: [ + { + type: 'oauth_authorization_code', + defaults: { + authorizationUrl: 'https://api.notion.com/v1/oauth/authorize', + tokenUrl: 'https://api.notion.com/v1/oauth/token', + }, + }, + ], headers: { 'Notion-Version': '2025-09-03', }, diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts index 3cc2d69825c33..ee40707e559eb 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts @@ -5,6 +5,7 @@ * 2.0. */ +import startCase from 'lodash/startCase'; import type { Logger } from '@kbn/core/server'; import type { ActionsConfigurationUtilities } from '../actions_config'; import type { ConnectorTokenClientContract } from '../types'; @@ -116,7 +117,10 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ configurationUtilities ); - const newAccessToken = `${tokenResult.tokenType} ${tokenResult.accessToken}`; + // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, + // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") + const normalizedTokenType = startCase(tokenResult.tokenType); + const newAccessToken = `${normalizedTokenType} ${tokenResult.accessToken}`; const newRefreshToken = tokenResult.refreshToken || connectorToken.refreshToken; // Calculate expiration times diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts index 8452b7ef9d53e..35512e0113d81 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts @@ -5,6 +5,7 @@ * 2.0. */ import type { Logger } from '@kbn/core/server'; +import startCase from 'lodash/startCase'; import type { ActionsConfigurationUtilities } from '../actions_config'; import type { ConnectorToken, ConnectorTokenClientContract } from '../types'; import { requestOAuthClientCredentialsToken } from './request_oauth_client_credentials_token'; @@ -79,7 +80,10 @@ export const getOAuthClientCredentialsAccessToken = async ({ }, configurationUtilities ); - accessToken = `${tokenResult.tokenType} ${tokenResult.accessToken}`; + // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, + // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") + const normalizedTokenType = startCase(tokenResult.tokenType); + accessToken = `${normalizedTokenType} ${tokenResult.accessToken}`; // try to update connector_token SO if (connectorId && connectorTokenClient) { diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts index 20f0b21933f27..9d8a939f17c68 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts @@ -5,6 +5,7 @@ * 2.0. */ import type { Logger } from '@kbn/core/server'; +import startCase from 'lodash/startCase'; import type { ActionsConfigurationUtilities } from '../actions_config'; import type { ConnectorToken, ConnectorTokenClientContract } from '../types'; import { createJWTAssertion } from './create_jwt_assertion'; @@ -89,7 +90,10 @@ export const getOAuthJwtAccessToken = async ({ logger, configurationUtilities ); - accessToken = `${tokenResult.tokenType} ${tokenResult.accessToken}`; + // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, + // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") + const normalizedTokenType = startCase(tokenResult.tokenType); + accessToken = `${normalizedTokenType} ${tokenResult.accessToken}`; // try to update connector_token SO if (connectorId && connectorTokenClient) { diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts index cbcaf1ce94f66..f1bc5dcb404b9 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts @@ -19,6 +19,7 @@ interface OAuthConnectorSecrets { clientSecret?: string; tokenUrl?: string; scope?: string; + redirectUri?: string; } /** @@ -33,6 +34,7 @@ interface OAuthConnectorConfig { clientId?: string; tokenUrl?: string; scope?: string; + redirectUri?: string; } /** @@ -42,6 +44,7 @@ export interface OAuthConfig { authorizationUrl: string; clientId: string; scope?: string; + redirectUri?: string; } /** @@ -121,6 +124,10 @@ export class OAuthAuthorizationService { const authorizationUrl = secrets.authorizationUrl || config?.authorizationUrl; const clientId = secrets.clientId || config?.clientId; const scope = secrets.scope || config?.scope; + // Filter out empty strings for redirectUri (treat as undefined) + const redirectUri = + (secrets.redirectUri && secrets.redirectUri !== '' ? secrets.redirectUri : undefined) || + (config?.redirectUri && config.redirectUri !== '' ? config.redirectUri : undefined); if (!authorizationUrl || !clientId) { throw new Error( @@ -134,6 +141,7 @@ export class OAuthAuthorizationService { authorizationUrl, clientId, scope, + redirectUri, }; } @@ -141,12 +149,21 @@ export class OAuthAuthorizationService { * Builds the redirect URI for OAuth callbacks * * The redirect URI is where the OAuth provider will send the user after authorization. - * It points to the oauth_callback route in this Kibana instance. + * If a custom redirectURI is provided, it will be used. Otherwise, it points to the + * oauth_callback route in this Kibana instance. * * @returns The complete redirect URI - * @throws Error if Kibana public base URL is not configured + * @throws Error if Kibana public base URL is not configured and no custom URI provided + * @param config */ - getRedirectUri(): string { + getRedirectUri(config: OAuthConnectorConfig): string { + // If user configured a custom redirect URI, use that + if (config.redirectUri) { + this.logger.debug(`Using custom redirect URI: ${config.redirectUri}`); + return config.redirectUri; + } + + // Otherwise, fallback to Kibana URL-based redirect URI if (!this.kibanaBaseUrl) { throw new Error( 'Kibana public URL not configured. Please set server.publicBaseUrl in kibana.yml' diff --git a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts index f69a91c3d547a..f1653f743130b 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts @@ -45,6 +45,7 @@ export async function requestOAuthAuthorizationCodeToken( OAUTH_AUTHORIZATION_CODE_GRANT_TYPE, configurationUtilities, logger, - rewriteBodyRequest(params) + rewriteBodyRequest(params), + true // Use HTTP Basic Auth for client credentials (required by Notion and recommended by OAuth 2.0 spec) ); } diff --git a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts index 9ef346e3ea196..ad5de84990bc9 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts @@ -42,6 +42,7 @@ export async function requestOAuthRefreshToken( OAUTH_REFRESH_TOKEN_GRANT_TYPE, configurationUtilities, logger, - rewriteBodyRequest(params) + rewriteBodyRequest(params), + true // Use HTTP Basic Auth for client credentials (required by some providers like Notion) ); } diff --git a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts index 4b7ed98aedf7e..6508e77618ead 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts @@ -12,6 +12,7 @@ import type { Logger } from '@kbn/core/server'; import { request } from './axios_utils'; import type { ActionsConfigurationUtilities } from '../actions_config'; import type { AsApiContract } from '../../common'; +import { getBasicAuthHeader } from './get_basic_auth_header'; export interface OAuthTokenResponse { tokenType: string; @@ -26,22 +27,34 @@ export async function requestOAuthToken( grantType: string, configurationUtilities: ActionsConfigurationUtilities, logger: Logger, - bodyRequest: AsApiContract + bodyRequest: AsApiContract, + useBasicAuth: boolean = false ): Promise { const axiosInstance = axios.create(); + // Extract client credentials for Basic Auth if needed + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const { client_id: clientId, client_secret: clientSecret, ...restBody } = bodyRequest as any; + + const requestData = { + ...(useBasicAuth ? restBody : bodyRequest), + grant_type: grantType, + }; + + const requestHeaders = { + ...(useBasicAuth && clientId && clientSecret + ? getBasicAuthHeader({ username: clientId, password: clientSecret }) + : {}), + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + }; + const res = await request({ axios: axiosInstance, url: tokenUrl, method: 'post', logger, - data: qs.stringify({ - ...bodyRequest, - grant_type: grantType, - }), - headers: { - 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', - }, + data: qs.stringify(requestData), + headers: requestHeaders, configurationUtilities, validateStatus: () => true, }); diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts index c8ee5a0d01175..bbc7fd8169f7f 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts @@ -5,7 +5,6 @@ * 2.0. */ -import type { TypeOf } from '@kbn/config-schema'; import { schema } from '@kbn/config-schema'; import type { IRouter, Logger, CoreSetup } from '@kbn/core/server'; import type { EncryptedSavedObjectsPluginStart } from '@kbn/encrypted-saved-objects-plugin/server'; @@ -22,9 +21,6 @@ import type { OAuthRateLimiter } from '../lib/oauth_rate_limiter'; const paramsSchema = schema.object({ connectorId: schema.string(), }); - -export type OAuthAuthorizeParams = TypeOf; - /** * Initiates OAuth2 Authorization Code flow * Returns authorization URL for user to visit @@ -112,7 +108,7 @@ export const oauthAuthorizeRoute = ( const oauthConfig = await oauthService.getOAuthConfig(connectorId); // Get redirect URI - const redirectUri = oauthService.getRedirectUri(); + const redirectUri = oauthService.getRedirectUri(oauthConfig); // Build return URL for post-OAuth redirect const kibanaReturnUrl = `${kibanaUrl}/app/management/insightsAndAlerting/triggersActionsConnectors/connectors`; diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index 089602293ad53..8fb54dce8ac8d 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -8,6 +8,7 @@ import { schema } from '@kbn/config-schema'; import type { IRouter, Logger } from '@kbn/core/server'; import type { EncryptedSavedObjectsPluginStart } from '@kbn/encrypted-saved-objects-plugin/server'; +import startCase from 'lodash/startCase'; import type { ILicenseState } from '../lib'; import { INTERNAL_BASE_ACTION_API_PATH } from '../../common'; import type { ActionsRequestHandlerContext } from '../types'; @@ -337,7 +338,10 @@ export const oauthCallbackRoute = ( tokenType: 'access_token', }); - const formattedToken = `${tokenResult.tokenType} ${tokenResult.accessToken}`; + // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, + // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") + const normalizedTokenType = startCase(tokenResult.tokenType); + const formattedToken = `${normalizedTokenType} ${tokenResult.accessToken}`; routeLogger.debug( `Successfully exchanged authorization code for access token for connectorId: ${oauthState.connectorId}` ); From f8d37b46f88ff2f47714ea792344b9ac728a9307 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 30 Dec 2025 18:01:27 +0100 Subject: [PATCH 16/49] Make useBasicAuth configurable --- .../src/auth_types/oauth_authorization_code.ts | 3 +++ .../src/auth_types/translations.ts | 12 ++++++++++++ .../kbn-connector-specs/src/specs/notion/notion.ts | 1 + .../src/specs/sharepoint_online/sharepoint_online.ts | 1 + .../lib/get_oauth_authorization_code_access_token.ts | 9 +++++++-- .../lib/request_oauth_authorization_code_token.ts | 5 +++-- .../server/lib/request_oauth_refresh_token.ts | 5 +++-- .../shared/actions/server/routes/oauth_callback.ts | 6 +++++- 8 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts index b8455cc93924c..4943dd257b17c 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts @@ -27,6 +27,9 @@ const authSchema = z .meta({ label: i18n.OAUTH_CLIENT_SECRET_LABEL, sensitive: true }), // when using z.url() it doesn't allow for empty urls even if it's an optional field redirectUri: z.string().meta({ label: i18n.OAUTH_REDIRECT_URI_LABEL }).optional(), + useBasicAuth: z.boolean().default(true).optional().meta({ + hidden: true, // Hidden from UI - uses connector spec defaults + }), }) .meta({ label: i18n.OAUTH_AUTHORIZATION_CODE_LABEL }); diff --git a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts index cb4e07634ed17..0023448d2fc8c 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts @@ -135,6 +135,18 @@ export const OAUTH_REDIRECT_URI_LABEL = i18n.translate('connectorSpecs.oauthRedi defaultMessage: 'Redirect URI', }); +export const OAUTH_USE_BASIC_AUTH_LABEL = i18n.translate('connectorSpecs.oauthUseBasicAuth.label', { + defaultMessage: 'Use HTTP Basic Authentication for token endpoint', +}); + +export const OAUTH_USE_BASIC_AUTH_HELP_TEXT = i18n.translate( + 'connectorSpecs.oauthUseBasicAuth.helpText', + { + defaultMessage: + 'Send client credentials via HTTP Basic Auth header instead of request body (recommended)', + } +); + export const CRT_AUTH_LABEL = i18n.translate('connectorSpecs.crt.label', { defaultMessage: 'SSL CRT and Key authentication', }); diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts index d054ec7d3c636..0e829b18d8e3d 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts @@ -28,6 +28,7 @@ export const NotionConnector: ConnectorSpec = { defaults: { authorizationUrl: 'https://api.notion.com/v1/oauth/authorize', tokenUrl: 'https://api.notion.com/v1/oauth/token', + useBasicAuth: true, // Notion requires HTTP Basic Auth for client credentials }, }, ], diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts index d8abf219e9d12..473f834ce2798 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts @@ -33,6 +33,7 @@ export const SharepointOnline: ConnectorSpec = { authorizationUrl: 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize', tokenUrl: 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token', scope: 'https://graph.microsoft.com/.default offline_access', + useBasicAuth: true, // Microsoft supports both methods, but Basic Auth is recommended }, }, ], diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts index ee40707e559eb..2cd77bb8de95a 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts @@ -15,6 +15,7 @@ export interface GetOAuthAuthorizationCodeConfig { clientId: string; tokenUrl: string; additionalFields?: Record; + useBasicAuth?: boolean; } export interface GetOAuthAuthorizationCodeSecrets { @@ -45,7 +46,7 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ connectorTokenClient, scope, }: GetOAuthAuthorizationCodeAccessTokenOpts): Promise => { - const { clientId, tokenUrl, additionalFields } = credentials.config; + const { clientId, tokenUrl, additionalFields, useBasicAuth } = credentials.config; const { clientSecret } = credentials.secrets; if (!clientId || !clientSecret) { @@ -53,6 +54,9 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ return null; } + // Default to true (OAuth 2.0 recommended practice) + const shouldUseBasicAuth = useBasicAuth ?? true; + // Get stored token const { connectorToken, hasErrors } = await connectorTokenClient.get({ connectorId, @@ -114,7 +118,8 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ scope, ...additionalFields, }, - configurationUtilities + configurationUtilities, + shouldUseBasicAuth ); // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, diff --git a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts index f1653f743130b..e5758a07fc3ae 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_authorization_code_token.ts @@ -38,7 +38,8 @@ export async function requestOAuthAuthorizationCodeToken( tokenUrl: string, logger: Logger, params: AuthorizationCodeOAuthRequestParams, - configurationUtilities: ActionsConfigurationUtilities + configurationUtilities: ActionsConfigurationUtilities, + useBasicAuth: boolean = true // Default to true (OAuth 2.0 recommended practice) ): Promise { return await requestOAuthToken( tokenUrl, @@ -46,6 +47,6 @@ export async function requestOAuthAuthorizationCodeToken( configurationUtilities, logger, rewriteBodyRequest(params), - true // Use HTTP Basic Auth for client credentials (required by Notion and recommended by OAuth 2.0 spec) + useBasicAuth ); } diff --git a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts index ad5de84990bc9..f91a828c58a0e 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_refresh_token.ts @@ -35,7 +35,8 @@ export async function requestOAuthRefreshToken( tokenUrl: string, logger: Logger, params: RefreshTokenOAuthRequestParams, - configurationUtilities: ActionsConfigurationUtilities + configurationUtilities: ActionsConfigurationUtilities, + useBasicAuth: boolean = true // Default to true (OAuth 2.0 recommended practice) ): Promise { return await requestOAuthToken( tokenUrl, @@ -43,6 +44,6 @@ export async function requestOAuthRefreshToken( configurationUtilities, logger, rewriteBodyRequest(params), - true // Use HTTP Basic Auth for client credentials (required by some providers like Notion) + useBasicAuth ); } diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index 8fb54dce8ac8d..2bc0a48a607f6 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -32,11 +32,13 @@ interface OAuthConnectorSecrets { clientId?: string; clientSecret?: string; tokenUrl?: string; + useBasicAuth?: boolean; } interface OAuthConnectorConfig { clientId?: string; tokenUrl?: string; + useBasicAuth?: boolean; } /** @@ -289,6 +291,7 @@ export const oauthCallbackRoute = ( const clientId = secrets.clientId || config?.clientId; const clientSecret = secrets.clientSecret; const tokenUrl = secrets.tokenUrl || config?.tokenUrl; + const useBasicAuth = secrets.useBasicAuth ?? config?.useBasicAuth ?? true; // Default to true (OAuth 2.0 recommended practice) if (!clientId || !clientSecret || !tokenUrl) { throw new Error( @@ -309,7 +312,8 @@ export const oauthCallbackRoute = ( clientId, clientSecret, }, - configurationUtilities + configurationUtilities, + useBasicAuth ); // Store tokens From 282b427e2f609ace27487dfe867a670bda435e22 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Wed, 31 Dec 2025 14:46:50 +0100 Subject: [PATCH 17/49] Cleanup --- .../shared/actions/server/lib/oauth_authorization_service.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts index f1bc5dcb404b9..36ba98b85f65a 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts @@ -124,10 +124,7 @@ export class OAuthAuthorizationService { const authorizationUrl = secrets.authorizationUrl || config?.authorizationUrl; const clientId = secrets.clientId || config?.clientId; const scope = secrets.scope || config?.scope; - // Filter out empty strings for redirectUri (treat as undefined) - const redirectUri = - (secrets.redirectUri && secrets.redirectUri !== '' ? secrets.redirectUri : undefined) || - (config?.redirectUri && config.redirectUri !== '' ? config.redirectUri : undefined); + const redirectUri = secrets.redirectUri || config?.redirectUri; if (!authorizationUrl || !clientId) { throw new Error( From 1b9911fd7183aee3d333b3c814f9fafe30f9d984 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Fri, 9 Jan 2026 19:33:18 +1100 Subject: [PATCH 18/49] Address first batch of comments --- .../src/specs/notion/notion.ts | 1 + .../sharepoint_online/sharepoint_online.ts | 1 - .../plugins/shared/actions/server/config.ts | 4 +- ...t_oauth_authorization_code_access_token.ts | 203 ++++++++++-------- .../server/lib/oauth_authorization_service.ts | 28 +-- .../actions/server/lib/oauth_state_client.ts | 11 +- .../plugins/shared/actions/server/plugin.ts | 3 + .../actions/server/routes/oauth_authorize.ts | 2 +- .../schemas/raw_connector_token/v2.ts | 9 +- 9 files changed, 140 insertions(+), 122 deletions(-) diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts index 0e829b18d8e3d..46f59ea7eb191 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/notion/notion.ts @@ -23,6 +23,7 @@ export const NotionConnector: ConnectorSpec = { auth: { types: [ + 'bearer', { type: 'oauth_authorization_code', defaults: { diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts index 473f834ce2798..d8abf219e9d12 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts @@ -33,7 +33,6 @@ export const SharepointOnline: ConnectorSpec = { authorizationUrl: 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize', tokenUrl: 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token', scope: 'https://graph.microsoft.com/.default offline_access', - useBasicAuth: true, // Microsoft supports both methods, but Basic Auth is recommended }, }, ], diff --git a/x-pack/platform/plugins/shared/actions/server/config.ts b/x-pack/platform/plugins/shared/actions/server/config.ts index 4bc6070cbf407..4f2dc18a9d6e1 100644 --- a/x-pack/platform/plugins/shared/actions/server/config.ts +++ b/x-pack/platform/plugins/shared/actions/server/config.ts @@ -76,11 +76,11 @@ const rateLimiterSchema = schema.recordOf( const oAuthRateLimitSchema = schema.object({ authorize: schema.object({ lookbackWindow: schema.string({ defaultValue: '1h', validate: validateDuration }), - limit: schema.number({ defaultValue: 10, min: 1, max: 1000 }), + limit: schema.number({ defaultValue: 100, min: 1, max: 1000 }), }), callback: schema.object({ lookbackWindow: schema.string({ defaultValue: '1h', validate: validateDuration }), - limit: schema.number({ defaultValue: 50, min: 1, max: 1000 }), + limit: schema.number({ defaultValue: 100, min: 1, max: 1000 }), }), }); diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts index 2cd77bb8de95a..e31f676de35d5 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts @@ -6,11 +6,23 @@ */ import startCase from 'lodash/startCase'; +import pLimit from 'p-limit'; import type { Logger } from '@kbn/core/server'; import type { ActionsConfigurationUtilities } from '../actions_config'; import type { ConnectorTokenClientContract } from '../types'; import { requestOAuthRefreshToken } from './request_oauth_refresh_token'; +// Per-connector locks to prevent concurrent token refreshes for the same connector +const tokenRefreshLocks = new Map>(); + +function getOrCreateLock(connectorId: string): ReturnType { + if (!tokenRefreshLocks.has(connectorId)) { + // Using p-limit with concurrency of 1 creates a mutex (only 1 operation at a time) + tokenRefreshLocks.set(connectorId, pLimit(1)); + } + return tokenRefreshLocks.get(connectorId)!; +} + export interface GetOAuthAuthorizationCodeConfig { clientId: string; tokenUrl: string; @@ -57,101 +69,106 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ // Default to true (OAuth 2.0 recommended practice) const shouldUseBasicAuth = useBasicAuth ?? true; - // Get stored token - const { connectorToken, hasErrors } = await connectorTokenClient.get({ - connectorId, - tokenType: 'access_token', - }); - - if (hasErrors) { - logger.warn(`Errors fetching connector token for connectorId: ${connectorId}`); - return null; - } - - // No token found - user must authorize first - if (!connectorToken) { - logger.warn( - `No access token found for connectorId: ${connectorId}. User must complete OAuth authorization flow.` - ); - return null; - } - - // Check if access token is still valid - const now = Date.now(); - const expiresAt = connectorToken.expiresAt ? Date.parse(connectorToken.expiresAt) : Infinity; + // Acquire lock for this connector to prevent concurrent token refreshes + const lock = getOrCreateLock(connectorId); - if (expiresAt > now) { - // Token still valid - logger.debug(`Using stored access token for connectorId: ${connectorId}`); - return connectorToken.token; - } - - // Access token expired - attempt refresh - if (!connectorToken.refreshToken) { - logger.warn( - `Access token expired and no refresh token available for connectorId: ${connectorId}. User must re-authorize.` - ); - return null; - } - - // Check if refresh token is expired - if ( - connectorToken.refreshTokenExpiresAt && - Date.parse(connectorToken.refreshTokenExpiresAt) <= now - ) { - logger.warn(`Refresh token expired for connectorId: ${connectorId}. User must re-authorize.`); - return null; - } - - // Refresh the token - logger.debug(`Refreshing access token for connectorId: ${connectorId}`); - const requestTokenStart = Date.now(); - - try { - const tokenResult = await requestOAuthRefreshToken( - tokenUrl, - logger, - { - refreshToken: connectorToken.refreshToken, - clientId, - clientSecret, - scope, - ...additionalFields, - }, - configurationUtilities, - shouldUseBasicAuth - ); - - // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, - // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") - const normalizedTokenType = startCase(tokenResult.tokenType); - const newAccessToken = `${normalizedTokenType} ${tokenResult.accessToken}`; - const newRefreshToken = tokenResult.refreshToken || connectorToken.refreshToken; - - // Calculate expiration times - const accessTokenExpiresAt = tokenResult.expiresIn - ? new Date(requestTokenStart + tokenResult.expiresIn * 1000).toISOString() - : undefined; - - const refreshTokenExpiresAt = tokenResult.refreshTokenExpiresIn - ? new Date(requestTokenStart + tokenResult.refreshTokenExpiresIn * 1000).toISOString() - : connectorToken.refreshTokenExpiresAt; - - // Update stored token - await connectorTokenClient.updateWithRefreshToken({ - id: connectorToken.id!, - token: newAccessToken, - refreshToken: newRefreshToken, - expiresAtMillis: accessTokenExpiresAt, - refreshTokenExpiresAtMillis: refreshTokenExpiresAt, + return await lock(async () => { + // Re-fetch token inside lock - another request may have already refreshed it + const { connectorToken, hasErrors } = await connectorTokenClient.get({ + connectorId, tokenType: 'access_token', }); - return newAccessToken; - } catch (err) { - logger.error( - `Failed to refresh access token for connectorId: ${connectorId}. Error: ${err.message}` - ); - return null; - } + if (hasErrors) { + logger.warn(`Errors fetching connector token for connectorId: ${connectorId}`); + return null; + } + + // No token found - user must authorize first + if (!connectorToken) { + logger.warn( + `No access token found for connectorId: ${connectorId}. User must complete OAuth authorization flow.` + ); + return null; + } + + // Check if access token is still valid (may have been refreshed by another request) + const now = Date.now(); + const expiresAt = connectorToken.expiresAt ? Date.parse(connectorToken.expiresAt) : Infinity; + + if (expiresAt > now) { + // Token still valid + logger.debug(`Using stored access token for connectorId: ${connectorId}`); + return connectorToken.token; + } + + // Access token expired - attempt refresh + if (!connectorToken.refreshToken) { + logger.warn( + `Access token expired and no refresh token available for connectorId: ${connectorId}. User must re-authorize.` + ); + return null; + } + + // Check if refresh token is expired + if ( + connectorToken.refreshTokenExpiresAt && + Date.parse(connectorToken.refreshTokenExpiresAt) <= now + ) { + logger.warn(`Refresh token expired for connectorId: ${connectorId}. User must re-authorize.`); + return null; + } + + // Refresh the token + logger.debug(`Refreshing access token for connectorId: ${connectorId}`); + const requestTokenStart = Date.now(); + + try { + const tokenResult = await requestOAuthRefreshToken( + tokenUrl, + logger, + { + refreshToken: connectorToken.refreshToken, + clientId, + clientSecret, + scope, + ...additionalFields, + }, + configurationUtilities, + shouldUseBasicAuth + ); + + // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, + // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") + const normalizedTokenType = startCase(tokenResult.tokenType); + const newAccessToken = `${normalizedTokenType} ${tokenResult.accessToken}`; + const newRefreshToken = tokenResult.refreshToken || connectorToken.refreshToken; + + // Calculate expiration times + const accessTokenExpiresAt = tokenResult.expiresIn + ? new Date(requestTokenStart + tokenResult.expiresIn * 1000).toISOString() + : undefined; + + const refreshTokenExpiresAt = tokenResult.refreshTokenExpiresIn + ? new Date(requestTokenStart + tokenResult.refreshTokenExpiresIn * 1000).toISOString() + : connectorToken.refreshTokenExpiresAt; + + // Update stored token + await connectorTokenClient.updateWithRefreshToken({ + id: connectorToken.id!, + token: newAccessToken, + refreshToken: newRefreshToken, + expiresAtMillis: accessTokenExpiresAt, + refreshTokenExpiresAtMillis: refreshTokenExpiresAt, + tokenType: 'access_token', + }); + + return newAccessToken; + } catch (err) { + logger.error( + `Failed to refresh access token for connectorId: ${connectorId}. Error: ${err.message}` + ); + return null; + } + }); }; diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts index 36ba98b85f65a..0e030e3546d9e 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts @@ -51,7 +51,7 @@ export interface OAuthConfig { * Parameters for building an OAuth authorization URL */ interface BuildAuthorizationUrlParams { - authorizationUrl: string; + baseAuthorizationUrl: string; clientId: string; scope?: string; redirectUri: string; @@ -59,6 +59,13 @@ interface BuildAuthorizationUrlParams { codeChallenge: string; } +interface ConnectorWithOAuth { + actionTypeId: string; + name: string; + config: OAuthConnectorConfig; + secrets: OAuthConnectorSecrets; +} + /** * Service for handling OAuth2 Authorization Code flow operations * @@ -111,12 +118,11 @@ export class OAuthAuthorizationService { this.validateOAuthConnector(config); // Fetch connector with decrypted secrets - const rawAction = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<{ - actionTypeId: string; - name: string; - config: OAuthConnectorConfig; - secrets: OAuthConnectorSecrets; - }>('action', connectorId); + const rawAction = + await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser( + 'action', + connectorId + ); const secrets = rawAction.attributes.secrets; @@ -132,8 +138,6 @@ export class OAuthAuthorizationService { ); } - this.logger.debug(`Retrieved OAuth config for connector ${connectorId}`); - return { authorizationUrl, clientId, @@ -175,9 +179,9 @@ export class OAuthAuthorizationService { * @returns The complete authorization URL as a string */ buildAuthorizationUrl(params: BuildAuthorizationUrlParams): string { - const { authorizationUrl, clientId, scope, redirectUri, state, codeChallenge } = params; + const { baseAuthorizationUrl, clientId, scope, redirectUri, state, codeChallenge } = params; - const authUrl = new URL(authorizationUrl); + const authUrl = new URL(baseAuthorizationUrl); authUrl.searchParams.set('client_id', clientId); authUrl.searchParams.set('response_type', 'code'); authUrl.searchParams.set('redirect_uri', redirectUri); @@ -189,8 +193,6 @@ export class OAuthAuthorizationService { authUrl.searchParams.set('scope', scope); } - this.logger.debug(`Built OAuth authorization URL for client ${clientId}`); - return authUrl.toString(); } } diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts index b24a694478a78..2a279f394fe7b 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts @@ -174,7 +174,7 @@ export class OAuthStateClient { } /** - * Delete OAuth state (should be called after successful token exchange) + * Delete OAuth state (should be called after a successful token exchange) */ public async delete(id: string): Promise { try { @@ -196,10 +196,11 @@ export class OAuthStateClient { perPage: 100, }); - await Promise.all( - result.saved_objects.map(async (obj) => - this.unsecuredSavedObjectsClient.delete(OAUTH_STATE_SAVED_OBJECT_TYPE, obj.id) - ) + await this.unsecuredSavedObjectsClient.bulkDelete( + result.saved_objects.map((obj) => ({ + type: OAUTH_STATE_SAVED_OBJECT_TYPE, + id: obj.id, + })) ); this.logger.debug(`Cleaned up ${result.saved_objects.length} expired OAuth states`); diff --git a/x-pack/platform/plugins/shared/actions/server/plugin.ts b/x-pack/platform/plugins/shared/actions/server/plugin.ts index 8c0fcfea80398..c81a76d0aa168 100644 --- a/x-pack/platform/plugins/shared/actions/server/plugin.ts +++ b/x-pack/platform/plugins/shared/actions/server/plugin.ts @@ -385,6 +385,9 @@ export class ActionsPlugin const oauthRateLimiter = new OAuthRateLimiter({ config: this.actionsConfig.oAuthRateLimit, }); + this.logger.info( + `OAuth rate limiter initialized with authorize limit: ${this.actionsConfig.oAuthRateLimit.authorize.limit}` + ); // Routes defineRoutes({ diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts index bbc7fd8169f7f..451ae69ba425f 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts @@ -132,7 +132,7 @@ export const oauthAuthorizeRoute = ( // Build authorization URL const authorizationUrl = oauthService.buildAuthorizationUrl({ - authorizationUrl: oauthConfig.authorizationUrl, + baseAuthorizationUrl: oauthConfig.authorizationUrl, clientId: oauthConfig.clientId, scope: oauthConfig.scope, redirectUri, diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v2.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v2.ts index 7f02ec9477bbc..b9e17acf4e471 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v2.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_connector_token/v2.ts @@ -6,15 +6,10 @@ */ import { schema } from '@kbn/config-schema'; +import { rawConnectorTokenSchema as rawConnectorTokenSchemaV1 } from './v1'; -export const rawConnectorTokenSchema = schema.object({ - createdAt: schema.string(), - connectorId: schema.string(), +export const rawConnectorTokenSchema = rawConnectorTokenSchemaV1.extends({ expiresAt: schema.maybe(schema.string()), // turned into an optional field - token: schema.string(), - tokenType: schema.string(), - updatedAt: schema.string(), - // added optional fields refreshToken: schema.maybe(schema.string()), refreshTokenExpiresAt: schema.maybe(schema.string()), }); From 28c188b8183211d0c2f4ef4a56f74fbe8b4bc604 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Fri, 9 Jan 2026 21:26:31 +1100 Subject: [PATCH 19/49] Address second batch of comments --- .../server/lib/oauth_rate_limiter.test.ts | 37 ------------------- .../server/lib/oauth_state_cleanup_task.ts | 7 +--- .../actions/server/lib/oauth_state_client.ts | 26 ++++++++----- .../actions/server/routes/oauth_authorize.ts | 16 +++----- .../actions/server/routes/oauth_callback.ts | 14 ++++++- 5 files changed, 36 insertions(+), 64 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.test.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.test.ts index 48907adf93287..45318eccef281 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_rate_limiter.test.ts @@ -190,41 +190,4 @@ describe('OAuthRateLimiter', () => { expect(rateLimiter.isRateLimited('user1', 'authorize')).toBe(false); }); }); - - describe('anonymous users', () => { - it('should handle anonymous user requests', () => { - const rateLimiter = new OAuthRateLimiter({ config: DEFAULT_CONFIG }); - - for (let i = 0; i < 5; i++) { - rateLimiter.log('anonymous', 'authorize'); - jest.advanceTimersByTime(1000); - } - - expect(rateLimiter.isRateLimited('anonymous', 'authorize')).toBe(false); - expect(rateLimiter.getLogs('anonymous', 'authorize')).toHaveLength(5); - }); - - it('should rate limit anonymous users independently from authenticated users', () => { - const config = { - authorize: { limit: 5, lookbackWindow: '1h' }, - callback: { limit: 50, lookbackWindow: '1h' }, - }; - const rateLimiter = new OAuthRateLimiter({ config }); - - // Anonymous hits limit - for (let i = 0; i < 5; i++) { - rateLimiter.log('anonymous', 'authorize'); - jest.advanceTimersByTime(1000); - } - - // Authenticated user under limit - for (let i = 0; i < 3; i++) { - rateLimiter.log('user1', 'authorize'); - jest.advanceTimersByTime(1000); - } - - expect(rateLimiter.isRateLimited('anonymous', 'authorize')).toBe(true); - expect(rateLimiter.isRateLimited('user1', 'authorize')).toBe(false); - }); - }); }); diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts index 5c5d84784aa51..efa829ae982ed 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_cleanup_task.ts @@ -19,7 +19,7 @@ export const OAUTH_STATE_CLEANUP_TASK_TYPE = 'actions:oauth_state_cleanup'; export const OAUTH_STATE_CLEANUP_TASK_ID = `Actions-${OAUTH_STATE_CLEANUP_TASK_TYPE}`; export const OAUTH_STATE_CLEANUP_SCHEDULE: IntervalSchedule = { interval: '30m' }; -interface TaskState { +interface TaskState extends Record { runs: number; last_cleanup_count: number; } @@ -56,7 +56,6 @@ function registerOAuthStateCleanupTask( title: 'OAuth state cleanup task', description: 'Periodically removes expired OAuth state objects', timeout: '1m', - // FIXME: WUT is wrong with the type here?!?! createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { return { run: async () => { @@ -77,10 +76,6 @@ function registerOAuthStateCleanupTask( const cleanupCount = await oauthStateClient.cleanupExpiredStates(); - logger.debug( - `OAuth state cleanup task completed. Cleaned up ${cleanupCount} expired states.` - ); - const updatedState: TaskState = { runs: (state.runs || 0) + 1, last_cleanup_count: cleanupCount, diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts index 2a279f394fe7b..d073961dc8dc2 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts @@ -190,21 +190,29 @@ export class OAuthStateClient { */ public async cleanupExpiredStates(): Promise { try { - const result = await this.unsecuredSavedObjectsClient.find({ + const finder = this.unsecuredSavedObjectsClient.createPointInTimeFinder({ type: OAUTH_STATE_SAVED_OBJECT_TYPE, filter: `${OAUTH_STATE_SAVED_OBJECT_TYPE}.attributes.expiresAt < "${new Date().toISOString()}"`, perPage: 100, }); - await this.unsecuredSavedObjectsClient.bulkDelete( - result.saved_objects.map((obj) => ({ - type: OAUTH_STATE_SAVED_OBJECT_TYPE, - id: obj.id, - })) - ); + let totalDeleted = 0; + + for await (const response of finder.find()) { + await this.unsecuredSavedObjectsClient.bulkDelete( + response.saved_objects.map((obj) => ({ + type: OAUTH_STATE_SAVED_OBJECT_TYPE, + id: obj.id, + })) + ); + + totalDeleted += response.saved_objects.length; + } + + await finder.close(); - this.logger.debug(`Cleaned up ${result.saved_objects.length} expired OAuth states`); - return result.saved_objects.length; + this.logger.debug(`Cleaned up ${totalDeleted} expired OAuth states`); + return totalDeleted; } catch (err) { this.logger.error(`Failed to cleanup expired OAuth states. Error: ${err.message}`); return 0; diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts index 451ae69ba425f..bc1de492ea932 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts @@ -51,11 +51,13 @@ export const oauthAuthorizeRoute = ( try { const core = await context.core; const routeLogger = logger.get('oauth_authorize'); - - // Check rate limit const currentUser = core.security.authc.getCurrentUser(); - const username = currentUser?.username || 'anonymous'; + if (!currentUser) { + throw new Error('User should be authenticated to initiate OAuth authorization.'); + } + const username = currentUser.username; + oauthRateLimiter.log(username, 'authorize'); if (oauthRateLimiter.isRateLimited(username, 'authorize')) { routeLogger.warn( `OAuth authorize rate limit exceeded for user: ${username}, connector: ${connectorId}` @@ -68,12 +70,8 @@ export const oauthAuthorizeRoute = ( }); } - // Log the request - oauthRateLimiter.log(username, 'authorize'); - const actionsClient = (await context.actions).getActionsClient(); - // Get encrypted saved objects client if (!getEncryptedSavedObjects) { throw new Error('EncryptedSavedObjects plugin not available'); } @@ -96,7 +94,6 @@ export const oauthAuthorizeRoute = ( }); } - // Create OAuth authorization service const oauthService = new OAuthAuthorizationService( actionsClient, encryptedSavedObjectsClient, @@ -107,7 +104,6 @@ export const oauthAuthorizeRoute = ( // Get OAuth configuration (validates connector and retrieves decrypted config) const oauthConfig = await oauthService.getOAuthConfig(connectorId); - // Get redirect URI const redirectUri = oauthService.getRedirectUri(oauthConfig); // Build return URL for post-OAuth redirect @@ -121,7 +117,6 @@ export const oauthAuthorizeRoute = ( }), logger: routeLogger, }); - const { state, codeChallenge } = await oauthStateClient.create({ connectorId, redirectUri, @@ -130,7 +125,6 @@ export const oauthAuthorizeRoute = ( kibanaReturnUrl, }); - // Build authorization URL const authorizationUrl = oauthService.buildAuthorizationUrl({ baseAuthorizationUrl: oauthConfig.authorizationUrl, clientId: oauthConfig.clientId, diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index 2bc0a48a607f6..fad771a3303d6 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -195,7 +195,19 @@ export const oauthCallbackRoute = ( // Check rate limit const currentUser = core.security.authc.getCurrentUser(); - const username = currentUser?.username || 'anonymous'; + if (!currentUser) { + return res.unauthorized({ + headers: { 'content-type': 'text/html' }, + body: generateOAuthCallbackPage({ + title: 'Authorization Failed', + heading: 'Authentication Required', + message: 'User should be authenticated to complete OAuth callback.', + details: 'Please log in and try again.', + isSuccess: false, + }), + }); + } + const username = currentUser.username; if (oauthRateLimiter.isRateLimited(username, 'callback')) { routeLogger.warn(`OAuth callback rate limit exceeded for user: ${username}`); From 62d5abd2bfc0740b5f6310e208b607d9bc79e10d Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Sat, 10 Jan 2026 09:56:05 +1100 Subject: [PATCH 20/49] Separate interfaces to avoid awkward optional id --- .../actions/server/lib/oauth_state_client.ts | 23 +++++++++++-------- .../actions/server/routes/oauth_callback.ts | 6 ++--- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts index d073961dc8dc2..c10247128a39b 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts @@ -14,8 +14,7 @@ import { OAUTH_STATE_SAVED_OBJECT_TYPE } from '../constants/saved_objects'; const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes -export interface OAuthState { - id?: string; +interface OAuthStateAttributes { state: string; codeVerifier: string; connectorId: string; @@ -28,6 +27,10 @@ export interface OAuthState { createdBy?: string; } +export interface OAuthState extends OAuthStateAttributes { + id: string; +} + interface ConstructorOptions { encryptedSavedObjectsClient: EncryptedSavedObjectsClient; unsecuredSavedObjectsClient: SavedObjectsClientContract; @@ -134,7 +137,7 @@ export class OAuthStateClient { */ public async get(stateParam: string): Promise { try { - const result = await this.unsecuredSavedObjectsClient.find({ + const result = await this.unsecuredSavedObjectsClient.find({ type: OAUTH_STATE_SAVED_OBJECT_TYPE, filter: `${OAUTH_STATE_SAVED_OBJECT_TYPE}.attributes.state: "${stateParam}"`, perPage: 1, @@ -156,7 +159,7 @@ export class OAuthStateClient { // Decrypt code verifier const decrypted = - await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser( + await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser( OAUTH_STATE_SAVED_OBJECT_TYPE, stateObject.id ); @@ -190,11 +193,13 @@ export class OAuthStateClient { */ public async cleanupExpiredStates(): Promise { try { - const finder = this.unsecuredSavedObjectsClient.createPointInTimeFinder({ - type: OAUTH_STATE_SAVED_OBJECT_TYPE, - filter: `${OAUTH_STATE_SAVED_OBJECT_TYPE}.attributes.expiresAt < "${new Date().toISOString()}"`, - perPage: 100, - }); + const finder = this.unsecuredSavedObjectsClient.createPointInTimeFinder( + { + type: OAUTH_STATE_SAVED_OBJECT_TYPE, + filter: `${OAUTH_STATE_SAVED_OBJECT_TYPE}.attributes.expiresAt < "${new Date().toISOString()}"`, + perPage: 100, + } + ); let totalDeleted = 0; diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index fad771a3303d6..cd1fbb97f3bef 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -209,6 +209,7 @@ export const oauthCallbackRoute = ( } const username = currentUser.username; + oauthRateLimiter.log(username, 'callback'); if (oauthRateLimiter.isRateLimited(username, 'callback')) { routeLogger.warn(`OAuth callback rate limit exceeded for user: ${username}`); return res.ok({ @@ -223,9 +224,6 @@ export const oauthCallbackRoute = ( }); } - // Log the request - oauthRateLimiter.log(username, 'callback'); - // Handle OAuth errors or missing parameters if (error || !code || !stateParam) { const errorMessage = error || 'Missing required OAuth parameters (code or state)'; @@ -373,7 +371,7 @@ export const oauthCallbackRoute = ( }); // Clean up state - await oauthStateClient.delete(oauthState.id!); + await oauthStateClient.delete(oauthState.id); // Redirect to Kibana const returnUrl = new URL(oauthState.kibanaReturnUrl); From 0c28e2e903846081f03f1731e20285b2eac63337 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Sat, 10 Jan 2026 10:07:37 +1100 Subject: [PATCH 21/49] Remove thin wrapper function --- .../actions_client/actions_client.test.ts | 4 +++ .../application/hooks/use_oauth_authorize.tsx | 21 ++++++++---- .../action_connector_api/oauth_authorize.ts | 32 ------------------- 3 files changed, 19 insertions(+), 38 deletions(-) delete mode 100644 x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/action_connector_api/oauth_authorize.ts diff --git a/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.test.ts b/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.test.ts index 629e406af3203..cae57ffbd8b9a 100644 --- a/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/actions_client/actions_client.test.ts @@ -536,6 +536,10 @@ describe('create()', () => { microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL, microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE, microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL, + oAuthRateLimit: { + authorize: { lookbackWindow: '1h', limit: 100 }, + callback: { lookbackWindow: '1h', limit: 100 }, + }, }); const localActionTypeRegistryParams = { diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx index 3a3e630a146e8..0d71212a5faef 100644 --- a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx +++ b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx @@ -7,7 +7,12 @@ import { useState, useCallback } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { oauthAuthorize } from '../lib/action_connector_api/oauth_authorize'; +import { INTERNAL_BASE_ACTION_API_PATH } from '../constants'; + +interface OAuthAuthorizeResponse { + authorizationUrl: string; + state: string; +} export function useOAuthAuthorize() { const { http } = useKibana().services; @@ -17,12 +22,16 @@ export function useOAuthAuthorize() { async (connectorId: string) => { setIsAuthorizing(true); try { - const { authorizationUrl } = await oauthAuthorize({ - http: http!, - connectorId, - }); + const { authorizationUrl } = await http!.post( + `${INTERNAL_BASE_ACTION_API_PATH}/connector/${encodeURIComponent( + connectorId + )}/_oauth_authorize`, + { + body: JSON.stringify({}), + } + ); - // Open authorization URL in new tab + // Open authorization URL in a new tab window.open(authorizationUrl, '_blank', 'noopener,noreferrer'); return true; diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/action_connector_api/oauth_authorize.ts b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/action_connector_api/oauth_authorize.ts deleted file mode 100644 index fc7dd565ea77b..0000000000000 --- a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/action_connector_api/oauth_authorize.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { HttpSetup } from '@kbn/core/public'; -import { INTERNAL_BASE_ACTION_API_PATH } from '../../constants'; - -interface OAuthAuthorizeResponse { - authorizationUrl: string; - state: string; -} - -export async function oauthAuthorize({ - http, - connectorId, -}: { - http: HttpSetup; - connectorId: string; -}): Promise { - const res = await http.post( - `${INTERNAL_BASE_ACTION_API_PATH}/connector/${encodeURIComponent( - connectorId - )}/_oauth_authorize`, - { - body: JSON.stringify({}), - } - ); - return res; -} From 48b485089b00db50d8038a4e17526a4db4cddb46 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Sat, 10 Jan 2026 10:14:34 +1100 Subject: [PATCH 22/49] Remove fields, log them instead --- .../shared/actions/server/lib/oauth_state_client.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts index c10247128a39b..69f35a32cf1a2 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts @@ -19,8 +19,6 @@ interface OAuthStateAttributes { codeVerifier: string; connectorId: string; redirectUri: string; - authorizationUrl: string; - scope?: string; kibanaReturnUrl: string; createdAt: string; expiresAt: string; @@ -96,6 +94,12 @@ export class OAuthStateClient { const now = new Date(); const expiresAt = new Date(now.getTime() + STATE_EXPIRATION_MS); + this.logger.debug( + `Creating OAuth state for connectorId "${connectorId}" with authorizationUrl: ${authorizationUrl}${ + scope ? `, scope: ${scope}` : '' + }` + ); + try { const result = await this.unsecuredSavedObjectsClient.create( OAUTH_STATE_SAVED_OBJECT_TYPE, @@ -105,8 +109,6 @@ export class OAuthStateClient { codeVerifier, connectorId, redirectUri, - authorizationUrl, - scope, kibanaReturnUrl, createdAt: now.toISOString(), expiresAt: expiresAt.toISOString(), From eb1f9f1dbe094ff92466ea1dd7da305a275b7d24 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Mon, 12 Jan 2026 19:15:20 +1100 Subject: [PATCH 23/49] Use core, remove authz url and scope from state SO --- .../actions/server/lib/oauth_state_client.ts | 11 +------ .../plugins/shared/actions/server/plugin.ts | 4 --- .../shared/actions/server/routes/index.ts | 30 ++----------------- .../actions/server/routes/oauth_authorize.ts | 13 +------- .../actions/server/routes/oauth_callback.ts | 13 +++----- 5 files changed, 9 insertions(+), 62 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts index 69f35a32cf1a2..9a729bcfba9ee 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_state_client.ts @@ -38,8 +38,6 @@ interface ConstructorOptions { interface CreateStateOptions { connectorId: string; redirectUri: string; - authorizationUrl: string; - scope?: string; kibanaReturnUrl: string; createdBy?: string; } @@ -79,8 +77,6 @@ export class OAuthStateClient { public async create({ connectorId, redirectUri, - authorizationUrl, - scope, kibanaReturnUrl, createdBy, }: CreateStateOptions): Promise<{ @@ -94,12 +90,7 @@ export class OAuthStateClient { const now = new Date(); const expiresAt = new Date(now.getTime() + STATE_EXPIRATION_MS); - this.logger.debug( - `Creating OAuth state for connectorId "${connectorId}" with authorizationUrl: ${authorizationUrl}${ - scope ? `, scope: ${scope}` : '' - }` - ); - + this.logger.debug(`Creating OAuth state for connectorId "${connectorId}"`); try { const result = await this.unsecuredSavedObjectsClient.create( OAUTH_STATE_SAVED_OBJECT_TYPE, diff --git a/x-pack/platform/plugins/shared/actions/server/plugin.ts b/x-pack/platform/plugins/shared/actions/server/plugin.ts index c81a76d0aa168..406dc6c52aed1 100644 --- a/x-pack/platform/plugins/shared/actions/server/plugin.ts +++ b/x-pack/platform/plugins/shared/actions/server/plugin.ts @@ -398,10 +398,6 @@ export class ActionsPlugin logger: this.logger, core, oauthRateLimiter, - getEncryptedSavedObjects: async () => { - const [, { encryptedSavedObjects }] = await core.getStartServices(); - return encryptedSavedObjects; - }, }); return { diff --git a/x-pack/platform/plugins/shared/actions/server/routes/index.ts b/x-pack/platform/plugins/shared/actions/server/routes/index.ts index ddb9bebe57cc5..c371b746e5ebd 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/index.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/index.ts @@ -7,7 +7,6 @@ import type { IRouter } from '@kbn/core/server'; import type { UsageCounter } from '@kbn/usage-collection-plugin/server'; -import type { EncryptedSavedObjectsPluginStart } from '@kbn/encrypted-saved-objects-plugin/server'; import type { Logger, CoreSetup } from '@kbn/core/server'; import { getAllConnectorsRoute } from './connector/get_all'; import { getAllConnectorsIncludingSystemRoute } from './connector/get_all_system'; @@ -35,22 +34,13 @@ export interface RouteOptions { licenseState: ILicenseState; actionsConfigUtils: ActionsConfigurationUtilities; usageCounter?: UsageCounter; - getEncryptedSavedObjects?: () => Promise; logger: Logger; core: CoreSetup; oauthRateLimiter: OAuthRateLimiter; } export function defineRoutes(opts: RouteOptions) { - const { - router, - licenseState, - actionsConfigUtils, - getEncryptedSavedObjects, - logger, - core, - oauthRateLimiter, - } = opts; + const { router, licenseState, actionsConfigUtils, logger, core, oauthRateLimiter } = opts; createConnectorRoute(router, licenseState); deleteConnectorRoute(router, licenseState); @@ -63,22 +53,8 @@ export function defineRoutes(opts: RouteOptions) { getGlobalExecutionKPIRoute(router, licenseState); getOAuthAccessToken(router, licenseState, actionsConfigUtils); - oauthAuthorizeRoute( - router, - licenseState, - logger, - core, - getEncryptedSavedObjects, - oauthRateLimiter - ); - oauthCallbackRoute( - router, - licenseState, - actionsConfigUtils, - logger, - getEncryptedSavedObjects, - oauthRateLimiter - ); + oauthAuthorizeRoute(router, licenseState, logger, core, oauthRateLimiter); + oauthCallbackRoute(router, licenseState, actionsConfigUtils, logger, core, oauthRateLimiter); getAllConnectorsIncludingSystemRoute(router, licenseState); listTypesWithSystemRoute(router, licenseState); } diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts index bc1de492ea932..1b8b53f89c40d 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts @@ -7,7 +7,6 @@ import { schema } from '@kbn/config-schema'; import type { IRouter, Logger, CoreSetup } from '@kbn/core/server'; -import type { EncryptedSavedObjectsPluginStart } from '@kbn/encrypted-saved-objects-plugin/server'; import type { ILicenseState } from '../lib'; import { INTERNAL_BASE_ACTION_API_PATH } from '../../common'; import type { ActionsRequestHandlerContext } from '../types'; @@ -30,7 +29,6 @@ export const oauthAuthorizeRoute = ( licenseState: ILicenseState, logger: Logger, coreSetup: CoreSetup, - getEncryptedSavedObjects: (() => Promise) | undefined, oauthRateLimiter: OAuthRateLimiter ) => { router.post( @@ -72,17 +70,10 @@ export const oauthAuthorizeRoute = ( const actionsClient = (await context.actions).getActionsClient(); - if (!getEncryptedSavedObjects) { - throw new Error('EncryptedSavedObjects plugin not available'); - } - - const encryptedSavedObjects = await getEncryptedSavedObjects(); + const [coreStart, { encryptedSavedObjects }] = await coreSetup.getStartServices(); const encryptedSavedObjectsClient = encryptedSavedObjects.getClient({ includedHiddenTypes: ['action', 'oauth_state'], }); - - // Get Kibana base URL - const [coreStart] = await coreSetup.getStartServices(); const kibanaUrl = coreStart.http.basePath.publicBaseUrl; if (!kibanaUrl) { @@ -120,8 +111,6 @@ export const oauthAuthorizeRoute = ( const { state, codeChallenge } = await oauthStateClient.create({ connectorId, redirectUri, - authorizationUrl: oauthConfig.authorizationUrl, - scope: oauthConfig.scope, kibanaReturnUrl, }); diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index cd1fbb97f3bef..774cf89415f31 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -6,9 +6,9 @@ */ import { schema } from '@kbn/config-schema'; -import type { IRouter, Logger } from '@kbn/core/server'; -import type { EncryptedSavedObjectsPluginStart } from '@kbn/encrypted-saved-objects-plugin/server'; +import type { CoreSetup, IRouter, Logger } from '@kbn/core/server'; import startCase from 'lodash/startCase'; +import type { ActionsPluginsStart } from '@kbn/actions-plugin/server/plugin'; import type { ILicenseState } from '../lib'; import { INTERNAL_BASE_ACTION_API_PATH } from '../../common'; import type { ActionsRequestHandlerContext } from '../types'; @@ -170,7 +170,7 @@ export const oauthCallbackRoute = ( licenseState: ILicenseState, configurationUtilities: ActionsConfigurationUtilities, logger: Logger, - getEncryptedSavedObjects: (() => Promise) | undefined, + coreSetup: CoreSetup, oauthRateLimiter: OAuthRateLimiter ) => { router.get( @@ -244,12 +244,7 @@ export const oauthCallbackRoute = ( } try { - // Get encrypted saved objects client - if (!getEncryptedSavedObjects) { - throw new Error('EncryptedSavedObjects plugin not available'); - } - - const encryptedSavedObjects = await getEncryptedSavedObjects(); + const [, { encryptedSavedObjects }] = await coreSetup.getStartServices(); const encryptedSavedObjectsClient = encryptedSavedObjects.getClient({ includedHiddenTypes: ['oauth_state'], }); From e9d25bbd0cb0215b9f207dabb2ffbe21eb87c343 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Mon, 12 Jan 2026 19:52:29 +1100 Subject: [PATCH 24/49] Small refactor for readability --- .../server/lib/connector_token_client.ts | 22 ++++--- .../server/lib/oauth_authorization_service.ts | 36 ++++++---- .../actions/server/routes/oauth_authorize.ts | 30 ++++----- .../actions/server/routes/oauth_callback.ts | 65 ++++++------------- 4 files changed, 69 insertions(+), 84 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts index 44c62544d1597..ca1bd38cba04a 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts @@ -312,19 +312,23 @@ export class ConnectorTokenClient { connectorId, accessToken, refreshToken, - expiresAtMillis, - refreshTokenExpiresAtMillis, + expiresIn, + refreshTokenExpiresIn, tokenType, }: { connectorId: string; accessToken: string; refreshToken?: string; - expiresAtMillis?: string; - refreshTokenExpiresAtMillis?: string; + expiresIn?: number; + refreshTokenExpiresIn?: number; tokenType?: string; }): Promise { const id = SavedObjectsUtils.generateId(); - const createTime = Date.now(); + const now = Date.now(); + const expiresInMillis = expiresIn ? new Date(now + expiresIn * 1000).toISOString() : undefined; + const refreshTokenExpiresInMillis = refreshTokenExpiresIn + ? new Date(now + refreshTokenExpiresIn * 1000).toISOString() + : undefined; try { const result = await this.unsecuredSavedObjectsClient.create( @@ -334,11 +338,11 @@ export class ConnectorTokenClient { connectorId, token: accessToken, refreshToken, - expiresAt: expiresAtMillis, - refreshTokenExpiresAt: refreshTokenExpiresAtMillis, + expiresAt: expiresInMillis, + refreshTokenExpiresAt: refreshTokenExpiresInMillis, tokenType: tokenType ?? 'access_token', - createdAt: new Date(createTime).toISOString(), - updatedAt: new Date(createTime).toISOString(), + createdAt: new Date(now).toISOString(), + updatedAt: new Date(now).toISOString(), }, isUndefined ), diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts index 0e030e3546d9e..190c887f36ab7 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts @@ -66,6 +66,13 @@ interface ConnectorWithOAuth { secrets: OAuthConnectorSecrets; } +interface ConstructorOptions { + actionsClient: ActionsClient; + encryptedSavedObjectsClient: EncryptedSavedObjectsClient; + kibanaBaseUrl: string; + logger: Logger; +} + /** * Service for handling OAuth2 Authorization Code flow operations * @@ -75,19 +82,22 @@ interface ConnectorWithOAuth { * - Building OAuth authorization URLs with PKCE parameters */ export class OAuthAuthorizationService { - /** - * Creates an instance of OAuthAuthorizationService - * @param actionsClient - Client for interacting with connectors - * @param encryptedSavedObjectsClient - Client for accessing encrypted connector secrets - * @param kibanaBaseUrl - The public base URL of the Kibana instance - * @param logger - Logger instance for debugging - */ - constructor( - private readonly actionsClient: ActionsClient, - private readonly encryptedSavedObjectsClient: EncryptedSavedObjectsClient, - private readonly kibanaBaseUrl: string, - private readonly logger: Logger - ) {} + private readonly actionsClient: ActionsClient; + private readonly encryptedSavedObjectsClient: EncryptedSavedObjectsClient; + private readonly kibanaBaseUrl: string; + private readonly logger: Logger; + + constructor({ + actionsClient, + encryptedSavedObjectsClient, + kibanaBaseUrl, + logger, + }: ConstructorOptions) { + this.actionsClient = actionsClient; + this.encryptedSavedObjectsClient = encryptedSavedObjectsClient; + this.kibanaBaseUrl = kibanaBaseUrl; + this.logger = logger; + } /** * Validates that a connector uses OAuth Authorization Code flow diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts index 1b8b53f89c40d..967be67dbeb21 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts @@ -49,12 +49,13 @@ export const oauthAuthorizeRoute = ( try { const core = await context.core; const routeLogger = logger.get('oauth_authorize'); + + // Check rate limit const currentUser = core.security.authc.getCurrentUser(); if (!currentUser) { throw new Error('User should be authenticated to initiate OAuth authorization.'); } const username = currentUser.username; - oauthRateLimiter.log(username, 'authorize'); if (oauthRateLimiter.isRateLimited(username, 'authorize')) { routeLogger.warn( @@ -68,14 +69,8 @@ export const oauthAuthorizeRoute = ( }); } - const actionsClient = (await context.actions).getActionsClient(); - const [coreStart, { encryptedSavedObjects }] = await coreSetup.getStartServices(); - const encryptedSavedObjectsClient = encryptedSavedObjects.getClient({ - includedHiddenTypes: ['action', 'oauth_state'], - }); const kibanaUrl = coreStart.http.basePath.publicBaseUrl; - if (!kibanaUrl) { return res.badRequest({ body: { @@ -85,24 +80,25 @@ export const oauthAuthorizeRoute = ( }); } - const oauthService = new OAuthAuthorizationService( - actionsClient, - encryptedSavedObjectsClient, - kibanaUrl, - routeLogger - ); - // Get OAuth configuration (validates connector and retrieves decrypted config) + const oauthService = new OAuthAuthorizationService({ + actionsClient: (await context.actions).getActionsClient(), + encryptedSavedObjectsClient: encryptedSavedObjects.getClient({ + includedHiddenTypes: ['action'], + }), + kibanaBaseUrl: kibanaUrl, + logger: routeLogger, + }); const oauthConfig = await oauthService.getOAuthConfig(connectorId); - const redirectUri = oauthService.getRedirectUri(oauthConfig); - // Build return URL for post-OAuth redirect const kibanaReturnUrl = `${kibanaUrl}/app/management/insightsAndAlerting/triggersActionsConnectors/connectors`; // Create OAuth state with PKCE const oauthStateClient = new OAuthStateClient({ - encryptedSavedObjectsClient, + encryptedSavedObjectsClient: encryptedSavedObjects.getClient({ + includedHiddenTypes: ['oauth_state'], + }), unsecuredSavedObjectsClient: core.savedObjects.getClient({ includedHiddenTypes: ['oauth_state'], }), diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index 774cf89415f31..8899892b8427e 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; import type { CoreSetup, IRouter, Logger } from '@kbn/core/server'; import startCase from 'lodash/startCase'; -import type { ActionsPluginsStart } from '@kbn/actions-plugin/server/plugin'; +import type { ActionsPluginsStart } from '../plugin'; import type { ILicenseState } from '../lib'; import { INTERNAL_BASE_ACTION_API_PATH } from '../../common'; import type { ActionsRequestHandlerContext } from '../types'; @@ -188,8 +188,6 @@ export const oauthCallbackRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const { code, state: stateParam, error, error_description: errorDescription } = req.query; - const core = await context.core; const routeLogger = logger.get('oauth_callback'); @@ -208,7 +206,6 @@ export const oauthCallbackRoute = ( }); } const username = currentUser.username; - oauthRateLimiter.log(username, 'callback'); if (oauthRateLimiter.isRateLimited(username, 'callback')) { routeLogger.warn(`OAuth callback rate limit exceeded for user: ${username}`); @@ -225,6 +222,7 @@ export const oauthCallbackRoute = ( } // Handle OAuth errors or missing parameters + const { code, state: stateParam, error, error_description: errorDescription } = req.query; if (error || !code || !stateParam) { const errorMessage = error || 'Missing required OAuth parameters (code or state)'; const details = errorDescription @@ -245,24 +243,18 @@ export const oauthCallbackRoute = ( try { const [, { encryptedSavedObjects }] = await coreSetup.getStartServices(); - const encryptedSavedObjectsClient = encryptedSavedObjects.getClient({ - includedHiddenTypes: ['oauth_state'], - }); - - // Get saved objects client for reading/writing OAuth state and tokens - const unsecuredSavedObjectsClient = core.savedObjects.getClient({ - includedHiddenTypes: ['oauth_state', 'connector_token'], - }); // Retrieve and validate state const oauthStateClient = new OAuthStateClient({ - encryptedSavedObjectsClient, - unsecuredSavedObjectsClient, + encryptedSavedObjectsClient: encryptedSavedObjects.getClient({ + includedHiddenTypes: ['oauth_state'], + }), + unsecuredSavedObjectsClient: core.savedObjects.getClient({ + includedHiddenTypes: ['oauth_state'], + }), logger: routeLogger, }); - const oauthState = await oauthStateClient.get(stateParam); - if (!oauthState) { return res.ok({ headers: { 'content-type': 'text/html' }, @@ -281,7 +273,6 @@ export const oauthCallbackRoute = ( const connectorEncryptedClient = encryptedSavedObjects.getClient({ includedHiddenTypes: ['action'], }); - const rawAction = await connectorEncryptedClient.getDecryptedAsInternalUser<{ actionTypeId: string; name: string; @@ -291,13 +282,11 @@ export const oauthCallbackRoute = ( const config = rawAction.attributes.config; const secrets = rawAction.attributes.secrets; - // Extract OAuth config - for connector specs, secrets are stored directly const clientId = secrets.clientId || config?.clientId; const clientSecret = secrets.clientSecret; const tokenUrl = secrets.tokenUrl || config?.tokenUrl; const useBasicAuth = secrets.useBasicAuth ?? config?.useBasicAuth ?? true; // Default to true (OAuth 2.0 recommended practice) - if (!clientId || !clientSecret || !tokenUrl) { throw new Error( 'Connector missing required OAuth configuration (clientId, clientSecret, tokenUrl)' @@ -320,48 +309,34 @@ export const oauthCallbackRoute = ( configurationUtilities, useBasicAuth ); + routeLogger.debug( + `Successfully exchanged authorization code for access token for connectorId: ${oauthState.connectorId}` + ); - // Store tokens - const connectorTokenEncryptedClient = encryptedSavedObjects.getClient({ - includedHiddenTypes: ['connector_token'], - }); - + // Store tokens - first delete any existing tokens for this connector then create a new token record const connectorTokenClient = new ConnectorTokenClient({ - encryptedSavedObjectsClient: connectorTokenEncryptedClient, - unsecuredSavedObjectsClient, + encryptedSavedObjectsClient: encryptedSavedObjects.getClient({ + includedHiddenTypes: ['connector_token'], + }), + unsecuredSavedObjectsClient: core.savedObjects.getClient({ + includedHiddenTypes: ['connector_token'], + }), logger: routeLogger, }); - - const now = Date.now(); - const accessTokenExpiresAt = tokenResult.expiresIn - ? new Date(now + tokenResult.expiresIn * 1000).toISOString() - : undefined; - - const refreshTokenExpiresAt = tokenResult.refreshTokenExpiresIn - ? new Date(now + tokenResult.refreshTokenExpiresIn * 1000).toISOString() - : undefined; - - // Delete any existing tokens first await connectorTokenClient.deleteConnectorTokens({ connectorId: oauthState.connectorId, tokenType: 'access_token', }); - // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") const normalizedTokenType = startCase(tokenResult.tokenType); const formattedToken = `${normalizedTokenType} ${tokenResult.accessToken}`; - routeLogger.debug( - `Successfully exchanged authorization code for access token for connectorId: ${oauthState.connectorId}` - ); - - // Create a new token record await connectorTokenClient.createWithRefreshToken({ connectorId: oauthState.connectorId, accessToken: formattedToken, refreshToken: tokenResult.refreshToken, - expiresAtMillis: accessTokenExpiresAt, - refreshTokenExpiresAtMillis: refreshTokenExpiresAt, + expiresIn: tokenResult.expiresIn, + refreshTokenExpiresIn: tokenResult.refreshTokenExpiresIn, tokenType: 'access_token', }); From 4296d5d853405ac0bd09f4b31257f31c029e4a70 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Mon, 12 Jan 2026 20:56:14 +1100 Subject: [PATCH 25/49] Make returnUrl a parameter --- .../actions/server/routes/oauth_authorize.ts | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts index 967be67dbeb21..66124e2af4d99 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts @@ -20,6 +20,11 @@ import type { OAuthRateLimiter } from '../lib/oauth_rate_limiter'; const paramsSchema = schema.object({ connectorId: schema.string(), }); + +const bodySchema = schema.object({ + returnUrl: schema.maybe(schema.uri({ scheme: ['http', 'https'] })), +}); + /** * Initiates OAuth2 Authorization Code flow * Returns authorization URL for user to visit @@ -37,6 +42,7 @@ export const oauthAuthorizeRoute = ( security: DEFAULT_ACTION_ROUTE_SECURITY, validate: { params: paramsSchema, + body: bodySchema, }, options: { access: 'internal', @@ -91,8 +97,28 @@ export const oauthAuthorizeRoute = ( }); const oauthConfig = await oauthService.getOAuthConfig(connectorId); const redirectUri = oauthService.getRedirectUri(oauthConfig); - // Build return URL for post-OAuth redirect - const kibanaReturnUrl = `${kibanaUrl}/app/management/insightsAndAlerting/triggersActionsConnectors/connectors`; + + // Validate and build return URL for post-OAuth redirect + const requestedReturnUrl = req.body?.returnUrl; + let kibanaReturnUrl: string; + + if (requestedReturnUrl) { + // Security: Validate that returnUrl is same-origin to prevent open redirect attacks + const returnUrlObj = new URL(requestedReturnUrl); + const kibanaUrlObj = new URL(kibanaUrl); + + if (returnUrlObj.origin !== kibanaUrlObj.origin) { + return res.badRequest({ + body: { + message: `returnUrl must be same origin as Kibana. Expected: ${kibanaUrlObj.origin}, Got: ${returnUrlObj.origin}`, + }, + }); + } + kibanaReturnUrl = requestedReturnUrl; + } else { + // Default to connectors management page + kibanaReturnUrl = `${kibanaUrl}/app/management/insightsAndAlerting/triggersActionsConnectors/connectors`; + } // Create OAuth state with PKCE const oauthStateClient = new OAuthStateClient({ From 5715715ba782986f679fad232aaf613ceafe81b6 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Mon, 12 Jan 2026 21:03:09 +1100 Subject: [PATCH 26/49] Rename route --- .../src/auth_types/oauth_authorization_code.ts | 8 ++++---- .../shared/actions/server/routes/oauth_authorize.ts | 2 +- .../public/application/hooks/use_oauth_authorize.tsx | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts index 4943dd257b17c..68783745f80b9 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts @@ -43,9 +43,9 @@ type AuthSchemaType = z.infer; * * ## How it works: * 1. User clicks the "Authorize" button in the connector UI - * 2. oauth_authorize route generates PKCE parameters and redirects the user to the provider's authorization page - * 3. User authorizes the app on the provider's site - * 4. Provider redirects back to the oauth_callback route with the authorization code + * 2. _start_oauth_flow route generates PKCE parameters and returns the provider's authorization URL + * 3. UI opens the authorization URL where user authorizes the app + * 4. Provider redirects back to the _oauth_callback route with the authorization code * 5. Callback route exchanges code for access/refresh tokens and stores them * 6. Tokens are auto-refreshed when expired during connector execution * @@ -79,7 +79,7 @@ type AuthSchemaType = z.infer; * ``` * * Users will fill in their client ID, client secret, and can customize URLs/scopes if needed. - * The oauth_authorize and oauth_callback routes are generic and work with any provider. + * The _start_oauth_flow and _oauth_callback routes are generic and work with any provider. */ export const OAuthAuthorizationCode: AuthTypeSpec = { id: 'oauth_authorization_code', diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts index 66124e2af4d99..cbb8ef852f03c 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts @@ -38,7 +38,7 @@ export const oauthAuthorizeRoute = ( ) => { router.post( { - path: `${INTERNAL_BASE_ACTION_API_PATH}/connector/{connectorId}/_oauth_authorize`, + path: `${INTERNAL_BASE_ACTION_API_PATH}/connector/{connectorId}/_start_oauth_flow`, security: DEFAULT_ACTION_ROUTE_SECURITY, validate: { params: paramsSchema, diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx index 0d71212a5faef..3394035437910 100644 --- a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx +++ b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/hooks/use_oauth_authorize.tsx @@ -25,7 +25,7 @@ export function useOAuthAuthorize() { const { authorizationUrl } = await http!.post( `${INTERNAL_BASE_ACTION_API_PATH}/connector/${encodeURIComponent( connectorId - )}/_oauth_authorize`, + )}/_start_oauth_flow`, { body: JSON.stringify({}), } From 4466144cad4a12a640279d00132d4422ec93b14b Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 13 Jan 2026 10:35:58 +1100 Subject: [PATCH 27/49] Try refresh token on 401 --- .../server/lib/connector_token_client.ts | 20 +-- .../actions/server/lib/get_axios_instance.ts | 119 ++++++++++++++++-- ...t_oauth_authorization_code_access_token.ts | 20 +-- 3 files changed, 125 insertions(+), 34 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts index ca1bd38cba04a..295709228d2ce 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.ts @@ -365,15 +365,15 @@ export class ConnectorTokenClient { id, token, refreshToken, - expiresAtMillis, - refreshTokenExpiresAtMillis, + expiresIn, + refreshTokenExpiresIn, tokenType, }: { id: string; token: string; refreshToken?: string; - expiresAtMillis?: string; - refreshTokenExpiresAtMillis?: string; + expiresIn?: number; + refreshTokenExpiresIn?: number; tokenType?: string; }): Promise { const { attributes, references, version } = @@ -381,7 +381,11 @@ export class ConnectorTokenClient { CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, id ); - const updateTime = Date.now(); + const now = Date.now(); + const expiresInMillis = expiresIn ? new Date(now + expiresIn * 1000).toISOString() : undefined; + const refreshTokenExpiresInMillis = refreshTokenExpiresIn + ? new Date(now + refreshTokenExpiresIn * 1000).toISOString() + : undefined; try { const updateOperation = () => { @@ -394,11 +398,11 @@ export class ConnectorTokenClient { ...attributesWithoutId, token, refreshToken: refreshToken ?? attributes.refreshToken, - expiresAt: expiresAtMillis, + expiresAt: expiresInMillis, refreshTokenExpiresAt: - refreshTokenExpiresAtMillis ?? attributes.refreshTokenExpiresAt, + refreshTokenExpiresInMillis ?? attributes.refreshTokenExpiresAt, tokenType: tokenType ?? 'access_token', - updatedAt: new Date(updateTime).toISOString(), + updatedAt: new Date(now).toISOString(), }, isUndefined ) as ConnectorToken, diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts index ed6f516c50da9..8679451e57e4a 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts @@ -7,6 +7,7 @@ import type { AxiosHeaderValue, AxiosInstance, InternalAxiosRequestConfig } from 'axios'; import axios from 'axios'; +import startCase from 'lodash/startCase'; import type { Logger } from '@kbn/core/server'; import type { GetTokenOpts } from '@kbn/connector-specs'; import type { ActionInfo } from './action_executor'; @@ -18,6 +19,7 @@ import { getBeforeRedirectFn } from './before_redirect'; import { getOAuthClientCredentialsAccessToken } from './get_oauth_client_credentials_access_token'; import { getOAuthAuthorizationCodeAccessToken } from './get_oauth_authorization_code_access_token'; import { getDeleteTokenAxiosInterceptor } from './delete_token_axios_interceptor'; +import { requestOAuthRefreshToken } from './request_oauth_refresh_token'; export type ConnectorInfo = Omit; @@ -29,6 +31,102 @@ interface GetAxiosInstanceOpts { type ValidatedSecrets = Record; +interface AxiosErrorWithRetry { + config: InternalAxiosRequestConfig & { _retry?: boolean }; + response?: { status: number }; + message: string; +} + +interface OAuth2RefreshParams { + clientId?: string; + clientSecret?: string; + tokenUrl?: string; + scope?: string; + useBasicAuth?: boolean; +} + +async function handleOAuth401Error({ + error, + connectorId, + secrets, + connectorTokenClient, + logger, + configurationUtilities, + axiosInstance, +}: { + error: AxiosErrorWithRetry; + connectorId: string; + secrets: OAuth2RefreshParams; + connectorTokenClient: ConnectorTokenClientContract; + logger: Logger; + configurationUtilities: ActionsConfigurationUtilities; + axiosInstance: AxiosInstance; +}): Promise { + // Prevent retry loops - only attempt refresh once per request + if (error.config._retry) { + return Promise.reject(error); + } + + error.config._retry = true; + logger.debug(`Attempting token refresh for connectorId ${connectorId} after 401 error`); + + try { + // Fetch current token to get refresh token + const { connectorToken, hasErrors } = await connectorTokenClient.get({ + connectorId, + tokenType: 'access_token', + }); + if (hasErrors || !connectorToken?.refreshToken) { + throw new Error('No refresh token available'); + } + + const { clientId, clientSecret, tokenUrl, scope, useBasicAuth } = secrets; + if (!clientId || !clientSecret || !tokenUrl) { + throw new Error('Missing required OAuth configuration (clientId, clientSecret, tokenUrl)'); + } + + // Request new access token using refresh token + const tokenResult = await requestOAuthRefreshToken( + tokenUrl, + logger, + { + refreshToken: connectorToken.refreshToken, + clientId, + clientSecret, + scope, + }, + configurationUtilities, + useBasicAuth ?? true + ); + + // Update stored token + const normalizedTokenType = startCase(tokenResult.tokenType); + const newAccessToken = `${normalizedTokenType} ${tokenResult.accessToken}`; + await connectorTokenClient.updateWithRefreshToken({ + id: connectorToken.id!, + token: newAccessToken, + refreshToken: tokenResult.refreshToken || connectorToken.refreshToken, + expiresIn: tokenResult.expiresIn, + refreshTokenExpiresIn: tokenResult.refreshTokenExpiresIn, + tokenType: 'access_token', + }); + + logger.debug(`Token refreshed successfully for connectorId ${connectorId}. Retrying request.`); + + // Update request with the new token and retry + error.config.headers.Authorization = newAccessToken; + return axiosInstance.request(error.config); + } catch (refreshError) { + const errorMessage = + refreshError instanceof Error ? refreshError.message : String(refreshError); + logger.error(`Token refresh failed for connectorId ${connectorId}: ${errorMessage}`); + + error.message = + 'Authentication failed: Unable to refresh access token. Please re-authorize the connector.'; + return Promise.reject(error); + } +} + export interface GetAxiosInstanceWithAuthFnOpts { additionalHeaders?: Record; connectorId: string; @@ -99,20 +197,21 @@ export const getAxiosInstanceWithAuth = ({ axiosInstance.interceptors.response.use(onFulfilled, onRejected); } - // Add response interceptor to handle 401 errors for OAuth connectors - if (authTypeId === 'oauth_authorization_code') { + // Add a response interceptor to handle 401 errors for OAuth authz code grant connectors + if (authTypeId === 'oauth_authorization_code' && connectorTokenClient) { axiosInstance.interceptors.response.use( (response) => response, (error) => { if (error.response?.status === 401) { - const message = - 'Authentication failed: The access token was rejected by the service (HTTP 401). ' + - 'This usually means the token has expired, been revoked, or does not have the required scopes. ' + - 'Please re-authorize the connector by clicking the "Authorize" button in the connector settings.'; - logger.error( - `OAuth 401 error for connectorId ${connectorId}: ${error.message}. ${message}` - ); - error.message = message; + return handleOAuth401Error({ + error, + connectorId, + secrets: secrets as OAuth2RefreshParams, + connectorTokenClient, + logger, + configurationUtilities, + axiosInstance, + }); } return Promise.reject(error); } diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts index e31f676de35d5..b878f881cf282 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts @@ -110,7 +110,7 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ return null; } - // Check if refresh token is expired + // Check if the refresh token is expired if ( connectorToken.refreshTokenExpiresAt && Date.parse(connectorToken.refreshTokenExpiresAt) <= now @@ -121,8 +121,6 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ // Refresh the token logger.debug(`Refreshing access token for connectorId: ${connectorId}`); - const requestTokenStart = Date.now(); - try { const tokenResult = await requestOAuthRefreshToken( tokenUrl, @@ -142,24 +140,14 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") const normalizedTokenType = startCase(tokenResult.tokenType); const newAccessToken = `${normalizedTokenType} ${tokenResult.accessToken}`; - const newRefreshToken = tokenResult.refreshToken || connectorToken.refreshToken; - - // Calculate expiration times - const accessTokenExpiresAt = tokenResult.expiresIn - ? new Date(requestTokenStart + tokenResult.expiresIn * 1000).toISOString() - : undefined; - - const refreshTokenExpiresAt = tokenResult.refreshTokenExpiresIn - ? new Date(requestTokenStart + tokenResult.refreshTokenExpiresIn * 1000).toISOString() - : connectorToken.refreshTokenExpiresAt; // Update stored token await connectorTokenClient.updateWithRefreshToken({ id: connectorToken.id!, token: newAccessToken, - refreshToken: newRefreshToken, - expiresAtMillis: accessTokenExpiresAt, - refreshTokenExpiresAtMillis: refreshTokenExpiresAt, + refreshToken: tokenResult.refreshToken || connectorToken.refreshToken, + expiresIn: tokenResult.expiresIn, + refreshTokenExpiresIn: tokenResult.refreshTokenExpiresIn, tokenType: 'access_token', }); From 404c7a76559dd72d20482c03508a9b0eeadbf0ac Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 13 Jan 2026 10:43:14 +1100 Subject: [PATCH 28/49] Undo custom redirectURI --- .../auth_types/oauth_authorization_code.ts | 2 -- .../src/auth_types/translations.ts | 4 --- .../server/lib/oauth_authorization_service.ts | 34 +++---------------- .../actions/server/routes/oauth_authorize.ts | 3 +- 4 files changed, 6 insertions(+), 37 deletions(-) diff --git a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts index 68783745f80b9..1d1962e62bd0f 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/oauth_authorization_code.ts @@ -25,8 +25,6 @@ const authSchema = z .string() .min(1, { message: i18n.OAUTH_CLIENT_SECRET_REQUIRED_MESSAGE }) .meta({ label: i18n.OAUTH_CLIENT_SECRET_LABEL, sensitive: true }), - // when using z.url() it doesn't allow for empty urls even if it's an optional field - redirectUri: z.string().meta({ label: i18n.OAUTH_REDIRECT_URI_LABEL }).optional(), useBasicAuth: z.boolean().default(true).optional().meta({ hidden: true, // Hidden from UI - uses connector spec defaults }), diff --git a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts index 0023448d2fc8c..1a0faee6cca51 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts @@ -131,10 +131,6 @@ export const OAUTH_AUTHORIZATION_URL_LABEL = i18n.translate( } ); -export const OAUTH_REDIRECT_URI_LABEL = i18n.translate('connectorSpecs.oauthRedirectURI.label', { - defaultMessage: 'Redirect URI', -}); - export const OAUTH_USE_BASIC_AUTH_LABEL = i18n.translate('connectorSpecs.oauthUseBasicAuth.label', { defaultMessage: 'Use HTTP Basic Authentication for token endpoint', }); diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts index 190c887f36ab7..421e6049d99db 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts @@ -5,7 +5,6 @@ * 2.0. */ -import type { Logger } from '@kbn/core/server'; import type { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; import type { ActionsClient } from '../actions_client'; import { INTERNAL_BASE_ACTION_API_PATH } from '../../common'; @@ -19,7 +18,6 @@ interface OAuthConnectorSecrets { clientSecret?: string; tokenUrl?: string; scope?: string; - redirectUri?: string; } /** @@ -34,7 +32,6 @@ interface OAuthConnectorConfig { clientId?: string; tokenUrl?: string; scope?: string; - redirectUri?: string; } /** @@ -44,7 +41,6 @@ export interface OAuthConfig { authorizationUrl: string; clientId: string; scope?: string; - redirectUri?: string; } /** @@ -70,7 +66,6 @@ interface ConstructorOptions { actionsClient: ActionsClient; encryptedSavedObjectsClient: EncryptedSavedObjectsClient; kibanaBaseUrl: string; - logger: Logger; } /** @@ -85,18 +80,11 @@ export class OAuthAuthorizationService { private readonly actionsClient: ActionsClient; private readonly encryptedSavedObjectsClient: EncryptedSavedObjectsClient; private readonly kibanaBaseUrl: string; - private readonly logger: Logger; - - constructor({ - actionsClient, - encryptedSavedObjectsClient, - kibanaBaseUrl, - logger, - }: ConstructorOptions) { + + constructor({ actionsClient, encryptedSavedObjectsClient, kibanaBaseUrl }: ConstructorOptions) { this.actionsClient = actionsClient; this.encryptedSavedObjectsClient = encryptedSavedObjectsClient; this.kibanaBaseUrl = kibanaBaseUrl; - this.logger = logger; } /** @@ -140,8 +128,6 @@ export class OAuthAuthorizationService { const authorizationUrl = secrets.authorizationUrl || config?.authorizationUrl; const clientId = secrets.clientId || config?.clientId; const scope = secrets.scope || config?.scope; - const redirectUri = secrets.redirectUri || config?.redirectUri; - if (!authorizationUrl || !clientId) { throw new Error( 'Connector missing required OAuth configuration (authorizationUrl, clientId)' @@ -152,7 +138,6 @@ export class OAuthAuthorizationService { authorizationUrl, clientId, scope, - redirectUri, }; } @@ -160,21 +145,12 @@ export class OAuthAuthorizationService { * Builds the redirect URI for OAuth callbacks * * The redirect URI is where the OAuth provider will send the user after authorization. - * If a custom redirectURI is provided, it will be used. Otherwise, it points to the - * oauth_callback route in this Kibana instance. + * It points to the oauth_callback route in this Kibana instance. * * @returns The complete redirect URI - * @throws Error if Kibana public base URL is not configured and no custom URI provided - * @param config + * @throws Error if Kibana public base URL is not configured */ - getRedirectUri(config: OAuthConnectorConfig): string { - // If user configured a custom redirect URI, use that - if (config.redirectUri) { - this.logger.debug(`Using custom redirect URI: ${config.redirectUri}`); - return config.redirectUri; - } - - // Otherwise, fallback to Kibana URL-based redirect URI + getRedirectUri(): string { if (!this.kibanaBaseUrl) { throw new Error( 'Kibana public URL not configured. Please set server.publicBaseUrl in kibana.yml' diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts index cbb8ef852f03c..a2d39e9452855 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_authorize.ts @@ -93,10 +93,9 @@ export const oauthAuthorizeRoute = ( includedHiddenTypes: ['action'], }), kibanaBaseUrl: kibanaUrl, - logger: routeLogger, }); const oauthConfig = await oauthService.getOAuthConfig(connectorId); - const redirectUri = oauthService.getRedirectUri(oauthConfig); + const redirectUri = oauthService.getRedirectUri(); // Validate and build return URL for post-OAuth redirect const requestedReturnUrl = req.body?.returnUrl; From 6cc6201c66465e5d1b0443d378e2f5e19c073067 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 13 Jan 2026 11:12:24 +1100 Subject: [PATCH 29/49] Add comment --- .../shared/actions/server/lib/oauth_authorization_service.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts index 421e6049d99db..50f7554717579 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts @@ -125,6 +125,8 @@ export class OAuthAuthorizationService { const secrets = rawAction.attributes.secrets; // Extract OAuth config - for connector specs, check secrets first, then config + // For connector specs, OAuth config is always in secrets (encrypted) + // Fallback to config for backwards compatibility with legacy connectors const authorizationUrl = secrets.authorizationUrl || config?.authorizationUrl; const clientId = secrets.clientId || config?.clientId; const scope = secrets.scope || config?.scope; From 9f55d45f213b2e8d24fc4cf22da00aba2047defc Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 13 Jan 2026 11:44:45 +1100 Subject: [PATCH 30/49] Remove TODO --- .../plugins/shared/actions/server/routes/oauth_callback.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index 8899892b8427e..ff7c1b62ab239 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -294,8 +294,6 @@ export const oauthCallbackRoute = ( } // Exchange authorization code for tokens - // TODO: couldn't this be either an Opaque token (as below) or a JWT token (requestOAuthJWTToken)? - // depending on the 3rd party's implementation of the token endpoint const tokenResult = await requestOAuthAuthorizationCodeToken( tokenUrl, logger, From 2dc86d414e23c8f87077d966971a51b0ec959e9d Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 13 Jan 2026 20:07:23 +1100 Subject: [PATCH 31/49] Remove lingering attribute --- .../actions/server/saved_objects/schemas/raw_oauth_state/v1.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts index 78a8de8b31ea1..f611b449c01ef 100644 --- a/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts +++ b/x-pack/platform/plugins/shared/actions/server/saved_objects/schemas/raw_oauth_state/v1.ts @@ -12,7 +12,6 @@ export const rawOAuthStateSchema = schema.object({ codeVerifier: schema.string(), connectorId: schema.string(), redirectUri: schema.string(), - authorizationUrl: schema.string(), scope: schema.maybe(schema.string()), kibanaReturnUrl: schema.string(), // in case of OAuth success, redirect to this URL createdAt: schema.string(), From e57ce06a94fbc94418fa6d28c5bf4148055f75a5 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 13 Jan 2026 20:29:38 +1100 Subject: [PATCH 32/49] Bump SO number --- .../saved-objects/server-internal/src/object_types/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/packages/saved-objects/server-internal/src/object_types/index.ts b/src/core/packages/saved-objects/server-internal/src/object_types/index.ts index 22fa224ed8efa..1ad59d2dc047d 100644 --- a/src/core/packages/saved-objects/server-internal/src/object_types/index.ts +++ b/src/core/packages/saved-objects/server-internal/src/object_types/index.ts @@ -11,4 +11,4 @@ export { registerCoreObjectTypes } from './registration'; // set minimum number of registered saved objects to ensure no object types are removed after 8.8 // declared in internal implementation explicitly to prevent unintended changes. -export const SAVED_OBJECT_TYPES_COUNT = 143 as const; +export const SAVED_OBJECT_TYPES_COUNT = 144 as const; From 19d3f6baeec7b22814d2a061a465eeafea35a2a2 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 13 Jan 2026 20:47:16 +1100 Subject: [PATCH 33/49] Add notification when oauth completed successfully --- .../actions/server/routes/oauth_callback.ts | 3 ++- .../components/actions_connectors_list.tsx | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index ff7c1b62ab239..bb261f8db62ea 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -341,8 +341,9 @@ export const oauthCallbackRoute = ( // Clean up state await oauthStateClient.delete(oauthState.id); - // Redirect to Kibana + // Redirect to Kibana with success indicator const returnUrl = new URL(oauthState.kibanaReturnUrl); + returnUrl.searchParams.set('oauth_authorization', 'success'); return res.redirected({ headers: { location: returnUrl.toString(), diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx index a2428a9683ec5..af7291f113cca 100644 --- a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx +++ b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx @@ -124,6 +124,28 @@ const ActionsConnectorsList = ({ chrome.docTitle.change(getCurrentDocTitle('connectors')); }, [chrome, setBreadcrumbs]); + // Check for OAuth authorization success and show toast notification + useEffect(() => { + const params = new URLSearchParams(location.search); + if (params.get('oauth_authorization') === 'success') { + toasts.addSuccess({ + title: i18n.translate( + 'xpack.triggersActionsUI.sections.actionsConnectorsList.oauthAuthorizationSuccessTitle', + { defaultMessage: 'Authorization successful' } + ), + text: i18n.translate( + 'xpack.triggersActionsUI.sections.actionsConnectorsList.oauthAuthorizationSuccessMessage', + { defaultMessage: 'Your connector has been authorized successfully.' } + ), + }); + + // Clean up the URL parameter + params.delete('oauth_authorization'); + const newUrl = `${location.pathname}${params.toString() ? `?${params.toString()}` : ''}`; + history.replace(newUrl); + } + }, [location.search, location.pathname, history, toasts]); + useEffect(() => { (async () => { try { From 4fd803ee1dfdd91b645bc0ff88db226f86dcdf14 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:50:18 +0000 Subject: [PATCH 34/49] Changes from node scripts/jest_integration -u src/core/server/integration_tests/ci_checks --- .../saved_objects/check_registered_types.test.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts index 83afdee815b85..5130593890eaf 100644 --- a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts +++ b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts @@ -89,7 +89,7 @@ describe('checking migration metadata changes on all registered SO types', () => "cloud-security-posture-settings": "f55e81e7c5a6706f7ed49ea045147169391f564eac65dc4fd862344557ca3eb0", "config": "d368f46c1a9920560f23b0d2793379995ee24bbff8e0438661bc3d9f528f4947", "config-global": "e306e70563eb2f3204aff45506f3ca1c3c67461971a45fba471c72bd8eb4435b", - "connector_token": "e485306ececb546f29923bbf776913b55fb40227daba71ce915b93f5ed2b8e60", + "connector_token": "6329f8628f381090b50e23c86723f97fba11d425d4bbc4ce63b0eb3a4f868fbe", "core-usage-stats": "0e76782718b2eef6104d2ddec46ed356339220997ad8da8d4f86433c3b46f77a", "csp-rule-template": "6fec028650a7aa0ef5a07d3d2906c32c2505da013adb2e51fa0e66bbf0ff70c5", "dashboard": "f57c3b6ba05cb4d2f06fbc5421bb160fa7c95cd0519ed1c516b2cad45f03c820", @@ -149,6 +149,7 @@ describe('checking migration metadata changes on all registered SO types', () => "ml-module": "cb77705b41ea0a35d8ba79b19014a30069e0e93a2cfb7ae8c6f20a79207d5daa", "ml-trained-model": "133305438dc0b60a6660c44f0d8183ad5ba079db8fdd4e4f4b5ab3a09d2f29b8", "monitoring-telemetry": "fa7c4f2a099b4f0539e571372a598601c2a0c65ba50f6c34df23b4d6925cdc53", + "oauth_state": "28e2c160836a0ec1962b888f90d4a17393b741b99569d5140078213b40d50ec1", "observability-onboarding-state": "43ca1749152c13fc75e7ad25e82b18f71375b8410cbd498e9ce1ce658f967b0a", "osquery-manager-usage-metric": "8833b9f812e9179897444c395761f9911945cfb77de9869c4e9b6ee6eeb0f573", "osquery-pack": "7ee940ea04c9c562406977efaa213050b2079c5bcc4e06ec56c8be6a85eb5ccd", @@ -528,6 +529,7 @@ describe('checking migration metadata changes on all registered SO types', () => "connector_token|global: 9c6972571df6c56a0d542bdca734a55a7a3859e5", "connector_token|mappings: 8c3f381518f3a37955cc7a434e72a81c11e28f1c", "connector_token|schemas: da39a3ee5e6b4b0d3255bfef95601890afd80709", + "connector_token|10.2.0: 53e0fe175a866f9b6b1454a190b60dd545499dbe2f8f9d369f95552c50cdd7e8", "connector_token|10.1.0: 8250fe57462059d5f1bf410e71e5150cf666d169e31749c0e2e129a4f7663120", "========================================================================================", "core-usage-stats|global: 0f6c6a66d1ec3ccababd15890476caf7f6f57700", @@ -977,6 +979,11 @@ describe('checking migration metadata changes on all registered SO types', () => "monitoring-telemetry|mappings: 400d044dff084cdfc58f413f5628494343bae327", "monitoring-telemetry|schemas: da39a3ee5e6b4b0d3255bfef95601890afd80709", "======================================================================", + "oauth_state|global: a665293b001c9e7b6e92c0a50a553b8163dbcd41", + "oauth_state|mappings: 04721e2fa836fed1f3f2e9c343d96ec5304f8f09", + "oauth_state|schemas: da39a3ee5e6b4b0d3255bfef95601890afd80709", + "oauth_state|10.1.0: 9d7468f4cfe8710457969b9bc5dfe33684a0f266696c9109cfa044153d526fd6", + "====================================================================================", "observability-onboarding-state|global: c226ba4dd0412c2d7fd7a01976461e9da00b78bf", "observability-onboarding-state|mappings: d6efe91e6efcc5e1b41fac37b731b715182939ce", "observability-onboarding-state|schemas: da39a3ee5e6b4b0d3255bfef95601890afd80709", @@ -1324,7 +1331,7 @@ describe('checking migration metadata changes on all registered SO types', () => "cloud-security-posture-settings": "10.1.0", "config": "10.2.0", "config-global": "10.0.0", - "connector_token": "10.1.0", + "connector_token": "10.2.0", "core-usage-stats": "10.0.0", "csp-rule-template": "10.0.0", "dashboard": "10.3.0", @@ -1384,6 +1391,7 @@ describe('checking migration metadata changes on all registered SO types', () => "ml-module": "10.0.0", "ml-trained-model": "10.0.0", "monitoring-telemetry": "10.0.0", + "oauth_state": "10.1.0", "observability-onboarding-state": "10.2.0", "osquery-manager-usage-metric": "10.0.0", "osquery-pack": "10.1.0", @@ -1477,7 +1485,7 @@ describe('checking migration metadata changes on all registered SO types', () => "cloud-security-posture-settings": "10.1.0", "config": "10.2.0", "config-global": "0.0.0", - "connector_token": "10.1.0", + "connector_token": "10.2.0", "core-usage-stats": "7.14.1", "csp-rule-template": "8.7.0", "dashboard": "10.3.0", @@ -1537,6 +1545,7 @@ describe('checking migration metadata changes on all registered SO types', () => "ml-module": "7.10.0", "ml-trained-model": "7.10.0", "monitoring-telemetry": "0.0.0", + "oauth_state": "10.1.0", "observability-onboarding-state": "10.2.0", "osquery-manager-usage-metric": "0.0.0", "osquery-pack": "10.1.0", From 356d885a7aa53da604983cdbfa4291b2586bd1ba Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 3 Feb 2026 12:46:08 +0100 Subject: [PATCH 35/49] Remove sharepoint and unused labels --- .github/CODEOWNERS | 1 - .../data-context-sources-connectors-list.md | 1 - docs/reference/toc.yml | 1 - .../kbn-connector-specs/src/all_specs.ts | 1 - .../src/auth_types/translations.ts | 12 - .../src/connector_icons_map.ts | 9 - .../specs/sharepoint_online/icon/index.tsx | 17 -- .../sharepoint_online/icon/sharepoint.svg | 1 - .../sharepoint_online.test.ts | 269 ------------------ .../sharepoint_online/sharepoint_online.ts | 117 -------- .../public/assets/icons/sharepoint_online.svg | 1 - 11 files changed, 430 deletions(-) delete mode 100644 src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/index.tsx delete mode 100644 src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/sharepoint.svg delete mode 100644 src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.test.ts delete mode 100644 src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts delete mode 100644 x-pack/platform/plugins/shared/content_connectors/public/assets/icons/sharepoint_online.svg diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index fc526ca0109ed..24629ac7170e9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2338,7 +2338,6 @@ src/platform/packages/shared/kbn-connector-specs/src/specs/notion/** @elastic/wo src/platform/packages/shared/kbn-connector-specs/src/specs/shodan/** @elastic/workflows-eng src/platform/packages/shared/kbn-connector-specs/src/specs/urlvoid/** @elastic/workflows-eng src/platform/packages/shared/kbn-connector-specs/src/specs/virustotal/** @elastic/workflows-eng -src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/** @elastic/workchat-eng # Gap fill feature has shared responsibility between response-ops and security-detection-engine /x-pack/platform/plugins/shared/alerting/common/routes/gaps @elastic/response-ops @elastic/security-detection-engine diff --git a/docs/reference/connectors-kibana/_snippets/data-context-sources-connectors-list.md b/docs/reference/connectors-kibana/_snippets/data-context-sources-connectors-list.md index c436e8502356f..86c32bcb767ab 100644 --- a/docs/reference/connectors-kibana/_snippets/data-context-sources-connectors-list.md +++ b/docs/reference/connectors-kibana/_snippets/data-context-sources-connectors-list.md @@ -7,7 +7,6 @@ * [AbuseIPDB](/reference/connectors-kibana/abuseipdb-action-type.md): Check IP reputation and report abusive IPs. * [AlienVault OTX](/reference/connectors-kibana/alienvault-otx-action-type.md): Retrieve community-driven threat intelligence. * [GreyNoise](/reference/connectors-kibana/greynoise-action-type.md): Detect and classify Internet scanning noise. -* [Sharepoint online](/reference/connectors-kibana/sharepoint-online-action-type.md): TODO: Add brief description. * [Shodan](/reference/connectors-kibana/shodan-action-type.md): Perform Internet-wide asset discovery and vulnerability scanning. * [URLVoid](/reference/connectors-kibana/urlvoid-action-type.md): Check domain and URL reputation using multi-engine scanning. * [VirusTotal](/reference/connectors-kibana/virustotal-action-type.md): Perform file scanning, URL analysis, and threat intelligence lookups. \ No newline at end of file diff --git a/docs/reference/toc.yml b/docs/reference/toc.yml index 5cbd54e35cdf7..ae6a218830915 100644 --- a/docs/reference/toc.yml +++ b/docs/reference/toc.yml @@ -78,7 +78,6 @@ toc: - file: connectors-kibana/greynoise-action-type.md - file: connectors-kibana/jina-action-type.md - file: connectors-kibana/notion-action-type.md - - file: connectors-kibana/sharepoint-online-action-type.md - file: connectors-kibana/shodan-action-type.md - file: connectors-kibana/urlvoid-action-type.md - file: connectors-kibana/virustotal-action-type.md diff --git a/src/platform/packages/shared/kbn-connector-specs/src/all_specs.ts b/src/platform/packages/shared/kbn-connector-specs/src/all_specs.ts index ef2593dc8c3aa..21b506295a48c 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/all_specs.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/all_specs.ts @@ -17,4 +17,3 @@ export * from './specs/shodan/shodan'; export * from './specs/urlvoid/urlvoid'; export * from './specs/virustotal/virustotal'; export * from './specs/jina/jina_reader'; -export * from './specs/sharepoint_online/sharepoint_online'; diff --git a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts index 1a0faee6cca51..c2975aea9ad5f 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/auth_types/translations.ts @@ -131,18 +131,6 @@ export const OAUTH_AUTHORIZATION_URL_LABEL = i18n.translate( } ); -export const OAUTH_USE_BASIC_AUTH_LABEL = i18n.translate('connectorSpecs.oauthUseBasicAuth.label', { - defaultMessage: 'Use HTTP Basic Authentication for token endpoint', -}); - -export const OAUTH_USE_BASIC_AUTH_HELP_TEXT = i18n.translate( - 'connectorSpecs.oauthUseBasicAuth.helpText', - { - defaultMessage: - 'Send client credentials via HTTP Basic Auth header instead of request body (recommended)', - } -); - export const CRT_AUTH_LABEL = i18n.translate('connectorSpecs.crt.label', { defaultMessage: 'SSL CRT and Key authentication', }); diff --git a/src/platform/packages/shared/kbn-connector-specs/src/connector_icons_map.ts b/src/platform/packages/shared/kbn-connector-specs/src/connector_icons_map.ts index 52dfabe33d528..fd7dacd4c1d31 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/connector_icons_map.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/connector_icons_map.ts @@ -64,13 +64,4 @@ export const ConnectorIconsMap: Map< '.urlvoid', lazy(() => import(/* webpackChunkName: "connectorIconUrlvoid" */ './specs/urlvoid/icon')), ], - [ - '.sharepointOnline', - lazy( - () => - import( - /* webpackChunkName: "connectorIconsharepointonline" */ './specs/sharepoint_online/icon' - ) - ), - ], ]); diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/index.tsx b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/index.tsx deleted file mode 100644 index 39a238c55ddb9..0000000000000 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React from 'react'; -import { EuiIcon } from '@elastic/eui'; -import type { ConnectorIconProps } from '../../../types'; -import sharepointIcon from './sharepoint.svg'; - -export default (props: ConnectorIconProps) => { - return ; -}; diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/sharepoint.svg b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/sharepoint.svg deleted file mode 100644 index f8b1afc5fbac6..0000000000000 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/icon/sharepoint.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.test.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.test.ts deleted file mode 100644 index 6126c3c3d07fc..0000000000000 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.test.ts +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import type { ActionContext } from '../../connector_spec'; -import { SharepointOnline } from './sharepoint_online'; - -describe('SharepointOnline', () => { - const mockClient = { - get: jest.fn(), - post: jest.fn(), - }; - - const mockContext = { - client: mockClient, - log: { debug: jest.fn(), error: jest.fn() }, - config: { region: 'NAM' }, - } as unknown as ActionContext; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - describe('search action', () => { - it('should search with default entity types', async () => { - const mockResponse = { - data: { - value: [ - { - hitsContainers: [ - { - hits: [ - { - hitId: '1', - resource: { - '@odata.type': '#microsoft.graph.driveItem', - name: 'Document.docx', - }, - }, - ], - total: 1, - }, - ], - }, - ], - }, - }; - mockClient.post.mockResolvedValue(mockResponse); - - const result = await SharepointOnline.actions.search.handler(mockContext, { - query: 'test document', - }); - - expect(mockClient.post).toHaveBeenCalledWith( - 'https://graph.microsoft.com/v1.0/search/query', - { - requests: [ - { - entityTypes: ['driveItem'], - query: { - queryString: 'test document', - }, - region: 'NAM', - }, - ], - } - ); - expect(result).toEqual(mockResponse.data); - }); - - it('should search with custom entity types', async () => { - const mockResponse = { - data: { - value: [ - { - hitsContainers: [ - { - hits: [ - { - hitId: '1', - resource: { - '@odata.type': '#microsoft.graph.site', - displayName: 'Test Site', - }, - }, - ], - total: 1, - }, - ], - }, - ], - }, - }; - mockClient.post.mockResolvedValue(mockResponse); - - await SharepointOnline.actions.search.handler(mockContext, { - query: 'project site', - entityTypes: ['site', 'list'], - }); - - expect(mockClient.post).toHaveBeenCalledWith( - 'https://graph.microsoft.com/v1.0/search/query', - { - requests: [ - { - entityTypes: ['site', 'list'], - query: { - queryString: 'project site', - }, - region: 'NAM', - }, - ], - } - ); - }); - - it('should include pagination parameters', async () => { - const mockResponse = { - data: { - value: [ - { - hitsContainers: [ - { - hits: [], - total: 100, - moreResultsAvailable: true, - }, - ], - }, - ], - }, - }; - mockClient.post.mockResolvedValue(mockResponse); - - await SharepointOnline.actions.search.handler(mockContext, { - query: 'documents', - from: 10, - size: 25, - }); - - expect(mockClient.post).toHaveBeenCalledWith( - 'https://graph.microsoft.com/v1.0/search/query', - { - requests: [ - { - entityTypes: ['driveItem'], - query: { - queryString: 'documents', - }, - region: 'NAM', - from: 10, - size: 25, - }, - ], - } - ); - }); - - it('should handle empty search results', async () => { - const mockResponse = { - data: { - value: [ - { - hitsContainers: [ - { - hits: [], - total: 0, - }, - ], - }, - ], - }, - }; - mockClient.post.mockResolvedValue(mockResponse); - - const result = await SharepointOnline.actions.search.handler(mockContext, { - query: 'nonexistent', - }); - - expect(result).toEqual(mockResponse.data); - }); - }); - - describe('test handler', () => { - it('should return success when API is accessible', async () => { - const mockResponse = { - data: { - id: 'root', - displayName: 'Contoso', - name: 'contoso', - webUrl: 'https://contoso.sharepoint.com', - }, - }; - mockClient.get.mockResolvedValue(mockResponse); - - if (!SharepointOnline.test) { - throw new Error('Test handler not defined'); - } - const result = await SharepointOnline.test.handler(mockContext); - - expect(mockClient.get).toHaveBeenCalledWith('https://graph.microsoft.com/v1.0/sites/root'); - expect(result).toEqual({ - ok: true, - message: 'Successfully connected to SharePoint Online: Contoso', - }); - }); - - it('should handle site without display name', async () => { - const mockResponse = { - data: { - id: 'root', - name: 'root', - }, - }; - mockClient.get.mockResolvedValue(mockResponse); - - if (!SharepointOnline.test) { - throw new Error('Test handler not defined'); - } - const result = await SharepointOnline.test.handler(mockContext); - - expect(result).toEqual({ - ok: true, - message: 'Successfully connected to SharePoint Online: Unknown', - }); - }); - - it('should return failure when API is not accessible', async () => { - mockClient.get.mockRejectedValue(new Error('Invalid credentials')); - - if (!SharepointOnline.test) { - throw new Error('Test handler not defined'); - } - const result = await SharepointOnline.test.handler(mockContext); - - expect(result.ok).toBe(false); - expect(result.message).toBe('Invalid credentials'); - }); - - it('should handle network errors', async () => { - mockClient.get.mockRejectedValue(new Error('Network timeout')); - - if (!SharepointOnline.test) { - throw new Error('Test handler not defined'); - } - const result = await SharepointOnline.test.handler(mockContext); - - expect(result.ok).toBe(false); - expect(result.message).toBe('Network timeout'); - }); - - it('should handle authentication errors', async () => { - mockClient.get.mockRejectedValue(new Error('401 Unauthorized')); - - if (!SharepointOnline.test) { - throw new Error('Test handler not defined'); - } - const result = await SharepointOnline.test.handler(mockContext); - - expect(result.ok).toBe(false); - expect(result.message).toBe('401 Unauthorized'); - }); - }); -}); diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts deleted file mode 100644 index d8abf219e9d12..0000000000000 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/sharepoint_online/sharepoint_online.ts +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { i18n } from '@kbn/i18n'; -import { z } from '@kbn/zod/v4'; -import type { ConnectorSpec } from '../../connector_spec'; - -/** - * SharePoint Online connector using OAuth2 Authorization Code flow with Microsoft Identity Platform. - */ -export const SharepointOnline: ConnectorSpec = { - metadata: { - id: '.sharepointOnline', - displayName: 'SharePoint Online', - description: i18n.translate('core.kibanaConnectorSpecs.sharepointOnline.metadata.description', { - defaultMessage: 'Search and explore SharePoint sites, pages, and content', - }), - minimumLicense: 'enterprise', - supportedFeatureIds: ['workflows'], - }, - - auth: { - types: [ - { - type: 'oauth_authorization_code', - defaults: { - authorizationUrl: 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize', - tokenUrl: 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token', - scope: 'https://graph.microsoft.com/.default offline_access', - }, - }, - ], - }, - - // No additional configuration needed beyond OAuth credentials - schema: z.object({}), - - actions: { - // https://learn.microsoft.com/en-us/graph/api/search-query - search: { - isTool: true, - input: z.object({ - query: z.string().describe('Search query'), - entityTypes: z - .array(z.enum(['site', 'list', 'listItem', 'drive', 'driveItem'])) - .optional() - .describe('Entity types to search'), - from: z.number().optional().describe('Offset for pagination'), - size: z.number().optional().describe('Number of results to return'), - }), - handler: async (ctx, input) => { - const typedInput = input as { - query: string; - entityTypes?: Array<'site' | 'list' | 'listItem' | 'drive' | 'driveItem'>; - from?: number; - size?: number; - }; - - const searchRequest = { - requests: [ - { - entityTypes: typedInput.entityTypes ?? ['driveItem'], - query: { - queryString: typedInput.query, - }, - ...(typedInput.from !== undefined && { from: typedInput.from }), - ...(typedInput.size !== undefined && { size: typedInput.size }), - }, - ], - }; - - try { - ctx.log.debug(`SharePoint search request: ${JSON.stringify(searchRequest, null, 2)}`); - const response = await ctx.client.post( - 'https://graph.microsoft.com/v1.0/search/query', - searchRequest - ); - return response.data; - } catch (error) { - ctx.log.error( - `SharePoint search failed: ${error.message}, Status: ${ - error.response?.status - }, Data: ${JSON.stringify(error.response?.data)}` - ); - throw error; - } - }, - }, - }, - - test: { - description: i18n.translate('core.kibanaConnectorSpecs.sharepointOnline.test.description', { - defaultMessage: 'Verifies SharePoint Online connection by checking API access', - }), - handler: async (ctx) => { - ctx.log.debug('SharePoint Online test handler'); - - try { - // Test connection by getting the root site - const response = await ctx.client.get('https://graph.microsoft.com/v1.0/sites/root'); - const siteName = response.data.displayName || 'Unknown'; - return { - ok: true, - message: `Successfully connected to SharePoint Online: ${siteName}`, - }; - } catch (error) { - return { ok: false, message: error.message }; - } - }, - }, -}; diff --git a/x-pack/platform/plugins/shared/content_connectors/public/assets/icons/sharepoint_online.svg b/x-pack/platform/plugins/shared/content_connectors/public/assets/icons/sharepoint_online.svg deleted file mode 100644 index f8b1afc5fbac6..0000000000000 --- a/x-pack/platform/plugins/shared/content_connectors/public/assets/icons/sharepoint_online.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 8925a8a1f1d6681da6d80c14d4089033cc4530f5 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 3 Feb 2026 13:01:38 +0100 Subject: [PATCH 36/49] Make callback public endpoint, remove sharepoint docs --- .../sharepoint-online-action-type.md | 175 ------------------ .../server/lib/oauth_authorization_service.ts | 4 +- .../actions/server/routes/oauth_callback.ts | 4 +- 3 files changed, 4 insertions(+), 179 deletions(-) delete mode 100644 docs/reference/connectors-kibana/sharepoint-online-action-type.md diff --git a/docs/reference/connectors-kibana/sharepoint-online-action-type.md b/docs/reference/connectors-kibana/sharepoint-online-action-type.md deleted file mode 100644 index 7c575fc469cdf..0000000000000 --- a/docs/reference/connectors-kibana/sharepoint-online-action-type.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -navigation_title: "SharePoint Online" -mapped_pages: - - https://www.elastic.co/guide/en/kibana/current/sharepoint-online-action-type.html -applies_to: - stack: preview - serverless: preview ---- - -# SharePoint Online connector [sharepoint-online-action-type] - -The SharePoint Online connector enables federated search capabilities across SharePoint sites, pages, and content using the Microsoft Graph API. - -## Create connectors in {{kib}} [define-sharepoint-online-ui] - -You can create connectors in **{{stack-manage-app}} > {{connectors-ui}}**. For example: - -### Connector configuration [sharepoint-online-connector-configuration] - -SharePoint Online connectors have the following configuration properties: - -Authorization URL -: The OAuth 2.0 authorization endpoint URL. Use the format: `https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize` - Replace `{tenant-id}` with your actual Microsoft Entra tenant ID. - -Token URL -: The OAuth 2.0 token endpoint URL. Use the format: `https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token` - Replace `{tenant-id}` with your actual Microsoft Entra tenant ID. - -Client ID -: The application (client) ID from your Microsoft Entra app registration. - -Client Secret -: The client secret generated for your Microsoft Entra application. - -Scope -: The OAuth scopes to request. Default: `https://graph.microsoft.com/.default offline_access` - - `https://graph.microsoft.com/.default` - Requests all delegated permissions configured for your app - - `offline_access` - Allows the connector to refresh access tokens automatically - - -## Test connectors [sharepoint-online-action-configuration] - -You can test connectors as you're creating or editing the connector in {{kib}}. The test verifies connectivity by accessing the root SharePoint site. - -The SharePoint Online connector has the following action: - -Search -: Search for content across SharePoint sites, lists, and drives using Microsoft Graph Search API. - - **query** (required): The search query string. - - **entityTypes** (optional): Array of entity types to search. Valid values: `site`, `list`, `listItem`, `drive`, `driveItem`. Defaults to `driveItem`. - - **from** (optional): Offset for pagination. - - **size** (optional): Number of results to return. - - -## Authorize the connector [sharepoint-online-authorization] - -The SharePoint Online connector uses OAuth 2.0 Authorization Code Grant flow, which requires user authorization through Microsoft login. - -After saving the connector configuration, click the **Authorize** button in the connector settings. This will: - -1. Open a new browser window with Microsoft login -2. Prompt you to sign in with your Microsoft 365 account -3. Ask you to consent to the requested permissions -4. Redirect back to {{kib}} with an authorization code -5. Automatically exchange the code for access and refresh tokens - -The connector will automatically refresh tokens when they expire. If you see authentication errors, click **Authorize** again to re-authenticate. - -## Get API credentials [sharepoint-online-api-credentials] - -To use the SharePoint Online connector, you need to create an app registration in Microsoft Entra (Azure AD) with OAuth 2.0 Authorization Code Grant flow: - -### Step 1: Register an application - -1. Go to the [Azure Portal](https://portal.azure.com/) -2. Navigate to **Microsoft Entra ID** > **App registrations** -3. Click **New registration** -4. Provide a name for your application (e.g., "Kibana SharePoint Connector") -5. Under **Supported account types**, select **Accounts in this organizational directory only** -6. Under **Redirect URI**: - - Select **Web** as the platform - - Enter your Kibana callback URL: `https://your-kibana-domain/internal/actions/connector/_oauth_callback` - - Replace `your-kibana-domain` with your actual Kibana domain (e.g., `https://localhost:5601` for local development) - - This must match the `server.publicBaseUrl` setting in your `kibana.yml` -7. Click **Register** - -### Step 2: Configure API permissions (DELEGATED permissions) - -**Important:** For OAuth Authorization Code flow, you must use **Delegated permissions**, not Application permissions. - -1. In your app registration, go to **API permissions** -2. Click **Add a permission** > **Microsoft Graph** > **Delegated permissions** -3. Add the following permissions: - - `Sites.Read.All` - Read items in all site collections - - `User.Read` - Sign in and read user profile (added by default) -4. Click **Add permissions** -5. Click **Grant admin consent for [your organization]** - - This step requires admin privileges - - Without admin consent, each user will need to consent individually - -**Why these permissions:** -- `Sites.Read.All` (delegated) - Required for the Microsoft Graph Search API to search SharePoint sites, lists, and documents on behalf of the signed-in user -- `User.Read` (delegated) - Required for basic user authentication - -**Note:** The connector uses the scope `https://graph.microsoft.com/.default`, which automatically includes all delegated permissions you've granted to the app. - -### Step 3: Create a client secret - -1. In your app registration, go to **Certificates & secrets** -2. Click **New client secret** -3. Provide a description (e.g., "Kibana SharePoint Connector Secret") -4. Select an expiration period (recommendation: 24 months) -5. Click **Add** -6. **Important:** Copy the secret **Value** immediately - it won't be shown again - - The **Secret ID** is not the same as the secret value - -### Step 4: Gather configuration information - -Collect the following values to configure your connector: - -**Tenant ID:** -- Found in **Microsoft Entra ID** > **Overview** > **Tenant ID** -- Or in your app registration **Overview** > **Directory (tenant) ID** - -**Client ID:** -- Found in your app registration **Overview** > **Application (client) ID** - -**Client Secret:** -- The value you copied in Step 3 - -**Authorization URL:** -- Format: `https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize` -- Replace `{tenant-id}` with your actual Tenant ID -- Example: `https://login.microsoftonline.com/12345678-1234-1234-1234-123456789abc/oauth2/v2.0/authorize` - -**Token URL:** -- Format: `https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token` -- Replace `{tenant-id}` with your actual Tenant ID -- Example: `https://login.microsoftonline.com/12345678-1234-1234-1234-123456789abc/oauth2/v2.0/token` - -**Scope:** -- Default: `https://graph.microsoft.com/.default offline_access` -- Do not modify unless you have specific requirements - -**Note:** The Region parameter is not supported when using OAuth Authorization Code flow with delegated permissions. If you need to use the Region parameter, you must use Application permissions (Client Credentials flow) instead. - -## Common issues [sharepoint-online-troubleshooting] - -**Authentication failed (HTTP 401)** - -This error typically means: -- The access token has expired, been revoked, or doesn't have required scopes -- **Solution:** Click the **Authorize** button again to re-authenticate - -**Invalid redirect URI** - -If authorization fails with a redirect URI error: -- Ensure the redirect URI in your app registration matches `https://your-kibana-domain/internal/actions/connector/_oauth_callback` -- Verify `server.publicBaseUrl` is set correctly in `kibana.yml` -- The redirect URI must be registered as **Web** platform, not **Single-page application** - -**Missing permissions** - -If searches return no results or permission errors: -- Verify you added **Delegated permissions**, not Application permissions -- Ensure admin consent was granted -- Check that `Sites.Read.All` delegated permission is present in **API permissions** - -**Token doesn't have required scopes** - -If you see scope-related errors: -- Verify the Scope field includes `https://graph.microsoft.com/.default offline_access` -- Re-authorize the connector after adding missing permissions in Azure AD -- Ensure admin consent was granted for all delegated permissions diff --git a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts index 50f7554717579..8c132279c42c6 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/oauth_authorization_service.ts @@ -7,7 +7,7 @@ import type { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; import type { ActionsClient } from '../actions_client'; -import { INTERNAL_BASE_ACTION_API_PATH } from '../../common'; +import { BASE_ACTION_API_PATH } from '../../common'; /** * OAuth connector secrets stored in encrypted saved objects @@ -158,7 +158,7 @@ export class OAuthAuthorizationService { 'Kibana public URL not configured. Please set server.publicBaseUrl in kibana.yml' ); } - return `${this.kibanaBaseUrl}${INTERNAL_BASE_ACTION_API_PATH}/connector/_oauth_callback`; + return `${this.kibanaBaseUrl}${BASE_ACTION_API_PATH}/connector/_oauth_callback`; } /** diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index bb261f8db62ea..cbd1822bd5e2f 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -10,7 +10,7 @@ import type { CoreSetup, IRouter, Logger } from '@kbn/core/server'; import startCase from 'lodash/startCase'; import type { ActionsPluginsStart } from '../plugin'; import type { ILicenseState } from '../lib'; -import { INTERNAL_BASE_ACTION_API_PATH } from '../../common'; +import { BASE_ACTION_API_PATH } from '../../common'; import type { ActionsRequestHandlerContext } from '../types'; import type { ActionsConfigurationUtilities } from '../actions_config'; import { DEFAULT_ACTION_ROUTE_SECURITY } from './constants'; @@ -175,7 +175,7 @@ export const oauthCallbackRoute = ( ) => { router.get( { - path: `${INTERNAL_BASE_ACTION_API_PATH}/connector/_oauth_callback`, + path: `${BASE_ACTION_API_PATH}/connector/_oauth_callback`, security: DEFAULT_ACTION_ROUTE_SECURITY, validate: { query: querySchema, From 8e9ba7a009aecd6193a6bb283f856568ac2f2f62 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 3 Feb 2026 13:04:07 +0100 Subject: [PATCH 37/49] bring back deleted icon --- .../content_connectors/public/assets/icons/sharepoint_online.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 x-pack/platform/plugins/shared/content_connectors/public/assets/icons/sharepoint_online.svg diff --git a/x-pack/platform/plugins/shared/content_connectors/public/assets/icons/sharepoint_online.svg b/x-pack/platform/plugins/shared/content_connectors/public/assets/icons/sharepoint_online.svg new file mode 100644 index 0000000000000..f8b1afc5fbac6 --- /dev/null +++ b/x-pack/platform/plugins/shared/content_connectors/public/assets/icons/sharepoint_online.svg @@ -0,0 +1 @@ + \ No newline at end of file From 71f4cd5e645f01274981cda84bc0e3dbbfea2627 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 3 Feb 2026 14:35:01 +0100 Subject: [PATCH 38/49] Reuse refresh logic when handling 401s --- .../actions/server/lib/get_axios_instance.ts | 83 +++++++------------ ...t_oauth_authorization_code_access_token.ts | 9 +- 2 files changed, 40 insertions(+), 52 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts index 8679451e57e4a..009b8b25a3a51 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.ts @@ -7,7 +7,6 @@ import type { AxiosHeaderValue, AxiosInstance, InternalAxiosRequestConfig } from 'axios'; import axios from 'axios'; -import startCase from 'lodash/startCase'; import type { Logger } from '@kbn/core/server'; import type { GetTokenOpts } from '@kbn/connector-specs'; import type { ActionInfo } from './action_executor'; @@ -19,7 +18,6 @@ import { getBeforeRedirectFn } from './before_redirect'; import { getOAuthClientCredentialsAccessToken } from './get_oauth_client_credentials_access_token'; import { getOAuthAuthorizationCodeAccessToken } from './get_oauth_authorization_code_access_token'; import { getDeleteTokenAxiosInterceptor } from './delete_token_axios_interceptor'; -import { requestOAuthRefreshToken } from './request_oauth_refresh_token'; export type ConnectorInfo = Omit; @@ -37,7 +35,7 @@ interface AxiosErrorWithRetry { message: string; } -interface OAuth2RefreshParams { +interface OAuth2AuthCodeParams { clientId?: string; clientSecret?: string; tokenUrl?: string; @@ -56,7 +54,7 @@ async function handleOAuth401Error({ }: { error: AxiosErrorWithRetry; connectorId: string; - secrets: OAuth2RefreshParams; + secrets: OAuth2AuthCodeParams; connectorTokenClient: ConnectorTokenClientContract; logger: Logger; configurationUtilities: ActionsConfigurationUtilities; @@ -70,61 +68,44 @@ async function handleOAuth401Error({ error.config._retry = true; logger.debug(`Attempting token refresh for connectorId ${connectorId} after 401 error`); - try { - // Fetch current token to get refresh token - const { connectorToken, hasErrors } = await connectorTokenClient.get({ - connectorId, - tokenType: 'access_token', - }); - if (hasErrors || !connectorToken?.refreshToken) { - throw new Error('No refresh token available'); - } - - const { clientId, clientSecret, tokenUrl, scope, useBasicAuth } = secrets; - if (!clientId || !clientSecret || !tokenUrl) { - throw new Error('Missing required OAuth configuration (clientId, clientSecret, tokenUrl)'); - } + const { clientId, clientSecret, tokenUrl, scope, useBasicAuth } = secrets; + if (!clientId || !clientSecret || !tokenUrl) { + error.message = + 'Authentication failed: Missing required OAuth configuration (clientId, clientSecret, tokenUrl).'; + return Promise.reject(error); + } - // Request new access token using refresh token - const tokenResult = await requestOAuthRefreshToken( - tokenUrl, - logger, - { - refreshToken: connectorToken.refreshToken, + // Use the shared token refresh function with mutex protection + const newAccessToken = await getOAuthAuthorizationCodeAccessToken({ + connectorId, + logger, + configurationUtilities, + credentials: { + config: { clientId, + tokenUrl, + useBasicAuth, + }, + secrets: { clientSecret, - scope, }, - configurationUtilities, - useBasicAuth ?? true - ); - - // Update stored token - const normalizedTokenType = startCase(tokenResult.tokenType); - const newAccessToken = `${normalizedTokenType} ${tokenResult.accessToken}`; - await connectorTokenClient.updateWithRefreshToken({ - id: connectorToken.id!, - token: newAccessToken, - refreshToken: tokenResult.refreshToken || connectorToken.refreshToken, - expiresIn: tokenResult.expiresIn, - refreshTokenExpiresIn: tokenResult.refreshTokenExpiresIn, - tokenType: 'access_token', - }); - - logger.debug(`Token refreshed successfully for connectorId ${connectorId}. Retrying request.`); - - // Update request with the new token and retry - error.config.headers.Authorization = newAccessToken; - return axiosInstance.request(error.config); - } catch (refreshError) { - const errorMessage = - refreshError instanceof Error ? refreshError.message : String(refreshError); - logger.error(`Token refresh failed for connectorId ${connectorId}: ${errorMessage}`); + }, + connectorTokenClient, + scope, + forceRefresh: true, + }); + if (!newAccessToken) { error.message = 'Authentication failed: Unable to refresh access token. Please re-authorize the connector.'; return Promise.reject(error); } + + logger.debug(`Token refreshed successfully for connectorId ${connectorId}. Retrying request.`); + + // Update request with the new token and retry + error.config.headers.Authorization = newAccessToken; + return axiosInstance.request(error.config); } export interface GetAxiosInstanceWithAuthFnOpts { @@ -206,7 +187,7 @@ export const getAxiosInstanceWithAuth = ({ return handleOAuth401Error({ error, connectorId, - secrets: secrets as OAuth2RefreshParams, + secrets: secrets as OAuth2AuthCodeParams, connectorTokenClient, logger, configurationUtilities, diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts index b878f881cf282..37fce49c2009b 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts @@ -44,6 +44,12 @@ interface GetOAuthAuthorizationCodeAccessTokenOpts { }; connectorTokenClient: ConnectorTokenClientContract; scope?: string; + /** + * When true, skip the expiration check and force a token refresh. + * Use this when you've received a 401 and know the token is invalid + * even if it hasn't "expired" according to the stored timestamp. + */ + forceRefresh?: boolean; } /** @@ -57,6 +63,7 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ credentials, connectorTokenClient, scope, + forceRefresh = false, }: GetOAuthAuthorizationCodeAccessTokenOpts): Promise => { const { clientId, tokenUrl, additionalFields, useBasicAuth } = credentials.config; const { clientSecret } = credentials.secrets; @@ -96,7 +103,7 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ const now = Date.now(); const expiresAt = connectorToken.expiresAt ? Date.parse(connectorToken.expiresAt) : Infinity; - if (expiresAt > now) { + if (!forceRefresh && expiresAt > now) { // Token still valid logger.debug(`Using stored access token for connectorId: ${connectorId}`); return connectorToken.token; From 62b5cacaf80eccc466e0c1a60fb5ca71b8272996 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 3 Feb 2026 15:07:41 +0100 Subject: [PATCH 39/49] Avoid any --- .../server/lib/request_oauth_jwt_token.ts | 2 +- .../actions/server/lib/request_oauth_token.ts | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_jwt_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_jwt_token.ts index 27100f8213758..b398f4fb3af5b 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_jwt_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_jwt_token.ts @@ -14,7 +14,7 @@ import type { RewriteResponseCase } from '../../common'; // for OAuth 2.0 Client Authentication and Authorization Grants https://datatracker.ietf.org/doc/html/rfc7523#section-8.1 export const OAUTH_JWT_BEARER_GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:jwt-bearer'; -interface JWTOAuthRequestParams { +export interface JWTOAuthRequestParams { assertion: string; clientId?: string; clientSecret?: string; diff --git a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts index 6508e77618ead..6a115f15778c7 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/request_oauth_token.ts @@ -9,10 +9,14 @@ import qs from 'query-string'; import axios from 'axios'; import stringify from 'json-stable-stringify'; import type { Logger } from '@kbn/core/server'; +import type { RefreshTokenOAuthRequestParams } from './request_oauth_refresh_token'; +import type { JWTOAuthRequestParams } from './request_oauth_jwt_token'; +import type { ClientCredentialsOAuthRequestParams } from './request_oauth_client_credentials_token'; import { request } from './axios_utils'; import type { ActionsConfigurationUtilities } from '../actions_config'; import type { AsApiContract } from '../../common'; import { getBasicAuthHeader } from './get_basic_auth_header'; +import type { AuthorizationCodeOAuthRequestParams } from './request_oauth_authorization_code_token'; export interface OAuthTokenResponse { tokenType: string; @@ -32,9 +36,17 @@ export async function requestOAuthToken( ): Promise { const axiosInstance = axios.create(); + type OAuthBodyRequest = + | AuthorizationCodeOAuthRequestParams + | ClientCredentialsOAuthRequestParams + | JWTOAuthRequestParams + | RefreshTokenOAuthRequestParams; // Extract client credentials for Basic Auth if needed - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const { client_id: clientId, client_secret: clientSecret, ...restBody } = bodyRequest as any; + const { + client_id: clientId, + client_secret: clientSecret, + ...restBody + } = bodyRequest as AsApiContract; const requestData = { ...(useBasicAuth ? restBody : bodyRequest), From b788df86d43231237858a07010afbd9f3716f9b9 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 3 Feb 2026 16:00:55 +0100 Subject: [PATCH 40/49] Quick checks fixes --- .../server-internal/src/object_types/index.ts | 2 +- .../shared/actions/server/actions_config.test.ts | 4 ++++ .../platform/plugins/shared/actions/server/config.ts | 4 ++-- .../integration_tests/axios_utils_connection.test.ts | 4 ++++ .../integration_tests/axios_utils_proxy.test.ts | 4 ++++ .../get_axios_instance_connection.test.ts | 4 ++++ .../server/lib/connector_token_client.mock.ts | 2 ++ .../actions/server/lib/custom_host_settings.test.ts | 4 ++++ .../plugins/shared/actions/server/plugin.test.ts | 12 ++++++++++++ 9 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/core/packages/saved-objects/server-internal/src/object_types/index.ts b/src/core/packages/saved-objects/server-internal/src/object_types/index.ts index 1ad59d2dc047d..a9f3af4f604ce 100644 --- a/src/core/packages/saved-objects/server-internal/src/object_types/index.ts +++ b/src/core/packages/saved-objects/server-internal/src/object_types/index.ts @@ -11,4 +11,4 @@ export { registerCoreObjectTypes } from './registration'; // set minimum number of registered saved objects to ensure no object types are removed after 8.8 // declared in internal implementation explicitly to prevent unintended changes. -export const SAVED_OBJECT_TYPES_COUNT = 144 as const; +export const SAVED_OBJECT_TYPES_COUNT = 145 as const; diff --git a/x-pack/platform/plugins/shared/actions/server/actions_config.test.ts b/x-pack/platform/plugins/shared/actions/server/actions_config.test.ts index f926424fb15cd..bb52d10a62b69 100644 --- a/x-pack/platform/plugins/shared/actions/server/actions_config.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/actions_config.test.ts @@ -42,6 +42,10 @@ const defaultActionsConfig: ActionsConfig = { microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL, microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE, microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL, + oAuthRateLimit: { + authorize: { lookbackWindow: '1h', limit: 100 }, + callback: { lookbackWindow: '1h', limit: 100 }, + }, }; describe('ensureUriAllowed', () => { diff --git a/x-pack/platform/plugins/shared/actions/server/config.ts b/x-pack/platform/plugins/shared/actions/server/config.ts index 4f2dc18a9d6e1..55a4b9e958a16 100644 --- a/x-pack/platform/plugins/shared/actions/server/config.ts +++ b/x-pack/platform/plugins/shared/actions/server/config.ts @@ -48,8 +48,8 @@ const connectorTypeSchema = schema.object({ maxAttempts: schema.maybe(schema.number({ min: MIN_MAX_ATTEMPTS, max: MAX_MAX_ATTEMPTS })), }); -// We leverage enabledActionTypes list by allowing the other plugins to overwrite it by using "setEnabledConnectorTypes" in the plugin setup. -// The list can be overwritten only if it's not already been set in the config. +// We leverage the enabledActionTypes list by allowing the other plugins to overwrite it by using "setEnabledConnectorTypes" in the plugin setup. +// The list can be overwritten only if it has not already been set in the config. const enabledConnectorTypesSchema = schema.arrayOf( schema.oneOf([schema.string(), schema.literal(EnabledActionTypes.Any)]), { diff --git a/x-pack/platform/plugins/shared/actions/server/integration_tests/axios_utils_connection.test.ts b/x-pack/platform/plugins/shared/actions/server/integration_tests/axios_utils_connection.test.ts index 52e257ae27acb..f19eb3b55506c 100644 --- a/x-pack/platform/plugins/shared/actions/server/integration_tests/axios_utils_connection.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/integration_tests/axios_utils_connection.test.ts @@ -716,6 +716,10 @@ const BaseActionsConfig: ActionsConfig = { microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL, microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE, microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL, + oAuthRateLimit: { + authorize: { lookbackWindow: '1h', limit: 100 }, + callback: { lookbackWindow: '1h', limit: 100 }, + }, }; function getACUfromConfig(config: Partial = {}): ActionsConfigurationUtilities { diff --git a/x-pack/platform/plugins/shared/actions/server/integration_tests/axios_utils_proxy.test.ts b/x-pack/platform/plugins/shared/actions/server/integration_tests/axios_utils_proxy.test.ts index 6f5dbb34d07e9..adb8cf8c445aa 100644 --- a/x-pack/platform/plugins/shared/actions/server/integration_tests/axios_utils_proxy.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/integration_tests/axios_utils_proxy.test.ts @@ -596,6 +596,10 @@ const BaseActionsConfig: ActionsConfig = { microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL, microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE, microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL, + oAuthRateLimit: { + authorize: { lookbackWindow: '1h', limit: 100 }, + callback: { lookbackWindow: '1h', limit: 100 }, + }, }; function getACUfromConfig(config: Partial = {}): ActionsConfigurationUtilities { diff --git a/x-pack/platform/plugins/shared/actions/server/integration_tests/get_axios_instance_connection.test.ts b/x-pack/platform/plugins/shared/actions/server/integration_tests/get_axios_instance_connection.test.ts index 2a4eec79f2c37..d805da65be50f 100644 --- a/x-pack/platform/plugins/shared/actions/server/integration_tests/get_axios_instance_connection.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/integration_tests/get_axios_instance_connection.test.ts @@ -795,6 +795,10 @@ const BaseActionsConfig: ActionsConfig = { microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL, microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE, microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL, + oAuthRateLimit: { + authorize: { lookbackWindow: '1h', limit: 100 }, + callback: { lookbackWindow: '1h', limit: 100 }, + }, }; function getACUfromConfig(config: Partial = {}): ActionsConfigurationUtilities { diff --git a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.mock.ts b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.mock.ts index 5990437b48159..e22d5f326d89f 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.mock.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/connector_token_client.mock.ts @@ -15,6 +15,8 @@ const createConnectorTokenClientMock = () => { update: jest.fn(), deleteConnectorTokens: jest.fn(), updateOrReplace: jest.fn(), + createWithRefreshToken: jest.fn(), + updateWithRefreshToken: jest.fn(), }; return mocked; }; diff --git a/x-pack/platform/plugins/shared/actions/server/lib/custom_host_settings.test.ts b/x-pack/platform/plugins/shared/actions/server/lib/custom_host_settings.test.ts index 440f0a8f9d0bc..7cff7f412e830 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/custom_host_settings.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/custom_host_settings.test.ts @@ -80,6 +80,10 @@ describe('custom_host_settings', () => { microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL, microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE, microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL, + oAuthRateLimit: { + authorize: { lookbackWindow: '1h', limit: 100 }, + callback: { lookbackWindow: '1h', limit: 100 }, + }, }; test('ensure it copies over the config parts that it does not touch', () => { diff --git a/x-pack/platform/plugins/shared/actions/server/plugin.test.ts b/x-pack/platform/plugins/shared/actions/server/plugin.test.ts index 653750a9bdca0..9ffc2a1e9bc60 100644 --- a/x-pack/platform/plugins/shared/actions/server/plugin.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/plugin.test.ts @@ -58,6 +58,10 @@ function getConfig(overrides = {}) { usage: { url: 'ca.path', }, + oAuthRateLimit: { + authorize: { lookbackWindow: '1h', limit: 100 }, + callback: { lookbackWindow: '1h', limit: 100 }, + }, ...overrides, }; } @@ -108,6 +112,10 @@ describe('Actions Plugin', () => { usage: { url: 'ca.path', }, + oAuthRateLimit: { + authorize: { lookbackWindow: '1h', limit: 100 }, + callback: { lookbackWindow: '1h', limit: 100 }, + }, }); plugin = new ActionsPlugin(context); coreSetup = coreMock.createSetup(); @@ -501,6 +509,10 @@ describe('Actions Plugin', () => { usage: { url: 'ca.path', }, + oAuthRateLimit: { + authorize: { lookbackWindow: '1h', limit: 100 }, + callback: { lookbackWindow: '1h', limit: 100 }, + }, }); plugin = new ActionsPlugin(context); coreSetup = coreMock.createSetup(); From cf1a14419662578d79fd5ce143894234d8b85faa Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 3 Feb 2026 16:25:28 +0100 Subject: [PATCH 41/49] Make CI green again --- .gitignore | 2 -- oas_docs/bundle.json | 33 +++++++++++++++++++ oas_docs/bundle.serverless.json | 33 +++++++++++++++++++ .../crowdstrike/token_manager.test.ts | 2 +- .../application/lib/check_oauth_auth_code.ts | 2 +- 5 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 oas_docs/bundle.json create mode 100644 oas_docs/bundle.serverless.json diff --git a/.gitignore b/.gitignore index 9d86e51eca6b3..c833286a76907 100644 --- a/.gitignore +++ b/.gitignore @@ -175,8 +175,6 @@ oas_docs/output/kibana.serverless.tmp*.yaml oas_docs/output/kibana.tmp*.yaml oas_docs/output/kibana.new.yaml oas_docs/output/kibana.serverless.new.yaml -oas_docs/bundle.json -oas_docs/bundle.serverless.json .codeql .dependency-graph-log.json diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json new file mode 100644 index 0000000000000..5396951add0f6 --- /dev/null +++ b/oas_docs/bundle.json @@ -0,0 +1,33 @@ +{ + "components": { + "schemas": {}, + "securitySchemes": { + "apiKeyAuth": { + "in": "header", + "name": "Authorization", + "type": "apiKey" + }, + "basicAuth": { + "scheme": "basic", + "type": "http" + } + } + }, + "info": { + "title": "Kibana HTTP APIs", + "version": "0.0.0" + }, + "openapi": "3.0.0", + "paths": {}, + "security": [ + { + "basicAuth": [] + } + ], + "servers": [ + { + "url": "http://localhost:5622" + } + ], + "tags": [] +} \ No newline at end of file diff --git a/oas_docs/bundle.serverless.json b/oas_docs/bundle.serverless.json new file mode 100644 index 0000000000000..5396951add0f6 --- /dev/null +++ b/oas_docs/bundle.serverless.json @@ -0,0 +1,33 @@ +{ + "components": { + "schemas": {}, + "securitySchemes": { + "apiKeyAuth": { + "in": "header", + "name": "Authorization", + "type": "apiKey" + }, + "basicAuth": { + "scheme": "basic", + "type": "http" + } + } + }, + "info": { + "title": "Kibana HTTP APIs", + "version": "0.0.0" + }, + "openapi": "3.0.0", + "paths": {}, + "security": [ + { + "basicAuth": [] + } + ], + "servers": [ + { + "url": "http://localhost:5622" + } + ], + "tags": [] +} \ No newline at end of file diff --git a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.test.ts b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.test.ts index 282b190d95587..725f9a4b4c993 100644 --- a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.test.ts +++ b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.test.ts @@ -83,7 +83,7 @@ describe('CrowdStrikeTokenManager', () => { jest.spyOn(connectorTokenClientMock, 'updateOrReplace').mockImplementation(async (options) => { // Calculate expiration time based on expiresInSec const expiresAt = new Date( - options.tokenRequestDate + options.expiresInSec * 1000 + options.tokenRequestDate + (options.expiresInSec ?? 0) * 1000 ).toISOString(); cachedTokenMock = createConnectorTokenMock({ connectorId: options.connectorId, diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/check_oauth_auth_code.ts b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/check_oauth_auth_code.ts index ff27e852496cd..9b2a30a83fe53 100644 --- a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/check_oauth_auth_code.ts +++ b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/check_oauth_auth_code.ts @@ -13,7 +13,7 @@ import type { ActionConnector } from '../../types'; * @returns True if the connector uses oauth_authorization_code auth type */ export function usesOAuthAuthorizationCode(connector: ActionConnector): boolean { - if (!connector || !connector.config) { + if (!connector || connector.isPreconfigured || connector.isSystemAction) { return false; } From e205b1f36fa28cd12246c6dd1cc103d616d92c40 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Tue, 3 Feb 2026 18:09:11 +0100 Subject: [PATCH 42/49] Default to true for isExpired --- .../server/connector_types/crowdstrike/token_manager.ts | 2 +- .../microsoft_defender_endpoint/o_auth_token_manager.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.ts b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.ts index 8eb76f3f70363..6e128b2edc359 100644 --- a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.ts +++ b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/crowdstrike/token_manager.ts @@ -45,7 +45,7 @@ export class CrowdStrikeTokenManager { const now = new Date(); now.setSeconds(now.getSeconds() - 5); // 5-second safety margin - const isExpired = token.expiresAt ? token.expiresAt < now.toISOString() : false; + const isExpired = token.expiresAt ? token.expiresAt < now.toISOString() : true; if (isExpired) { this.logger.debug(`Cached access token expired at [${token.expiresAt}]`); diff --git a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/o_auth_token_manager.ts b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/o_auth_token_manager.ts index 3b8d80d20bfe4..f4d26e37fb348 100644 --- a/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/o_auth_token_manager.ts +++ b/x-pack/platform/plugins/shared/stack_connectors/server/connector_types/microsoft_defender_endpoint/o_auth_token_manager.ts @@ -47,7 +47,7 @@ export class OAuthTokenManager { const now = new Date(); now.setSeconds(now.getSeconds() - 5); // Allows for a threshold of -5s before considering the token expired - const isExpired = token.expiresAt ? token.expiresAt < now.toISOString() : false; + const isExpired = token.expiresAt ? token.expiresAt < now.toISOString() : true; if (isExpired) { this.logger.debug(`Cached access token expired at [${token.expiresAt}]`); From 67a0546c56d6296ac2e5d42433b4dbc0f2ff2d36 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 3 Feb 2026 17:45:07 +0000 Subject: [PATCH 43/49] Changes from yarn openapi:bundle --- oas_docs/bundle.json | 103291 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 103288 insertions(+), 3 deletions(-) diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json index 5396951add0f6..f05b5d1a8ff25 100644 --- a/oas_docs/bundle.json +++ b/oas_docs/bundle.json @@ -1,6 +1,369 @@ { "components": { - "schemas": {}, + "schemas": { + "core_status_redactedResponse": { + "additionalProperties": false, + "description": "A minimal representation of Kibana's operational status.", + "properties": { + "status": { + "additionalProperties": false, + "properties": { + "overall": { + "additionalProperties": false, + "properties": { + "level": { + "description": "Service status levels as human and machine readable values.", + "enum": [ + "available", + "degraded", + "unavailable", + "critical" + ], + "type": "string" + } + }, + "required": [ + "level" + ], + "type": "object" + } + }, + "required": [ + "overall" + ], + "type": "object" + } + }, + "required": [ + "status" + ], + "type": "object" + }, + "core_status_response": { + "additionalProperties": false, + "description": "Kibana's operational status as well as a detailed breakdown of plugin statuses indication of various loads (like event loop utilization and network traffic) at time of request.", + "properties": { + "metrics": { + "additionalProperties": false, + "description": "Metric groups collected by Kibana.", + "properties": { + "collection_interval_in_millis": { + "description": "The interval at which metrics should be collected.", + "type": "number" + }, + "elasticsearch_client": { + "additionalProperties": false, + "description": "Current network metrics of Kibana's Elasticsearch client.", + "properties": { + "totalActiveSockets": { + "description": "Count of network sockets currently in use.", + "type": "number" + }, + "totalIdleSockets": { + "description": "Count of network sockets currently idle.", + "type": "number" + }, + "totalQueuedRequests": { + "description": "Count of requests not yet assigned to sockets.", + "type": "number" + } + }, + "required": [ + "totalActiveSockets", + "totalIdleSockets", + "totalQueuedRequests" + ], + "type": "object" + }, + "last_updated": { + "description": "The time metrics were collected.", + "type": "string" + } + }, + "required": [ + "elasticsearch_client", + "last_updated", + "collection_interval_in_millis" + ], + "type": "object" + }, + "name": { + "description": "Kibana instance name.", + "type": "string" + }, + "status": { + "additionalProperties": false, + "properties": { + "core": { + "additionalProperties": false, + "description": "Statuses of core Kibana services.", + "properties": { + "elasticsearch": { + "additionalProperties": false, + "properties": { + "detail": { + "description": "Human readable detail of the service status.", + "type": "string" + }, + "documentationUrl": { + "description": "A URL to further documentation regarding this service.", + "type": "string" + }, + "level": { + "description": "Service status levels as human and machine readable values.", + "enum": [ + "available", + "degraded", + "unavailable", + "critical" + ], + "type": "string" + }, + "meta": { + "additionalProperties": {}, + "description": "An unstructured set of extra metadata about this service.", + "type": "object" + }, + "summary": { + "description": "A human readable summary of the service status.", + "type": "string" + } + }, + "required": [ + "level", + "summary", + "meta" + ], + "type": "object" + }, + "http": { + "additionalProperties": false, + "properties": { + "detail": { + "description": "Human readable detail of the service status.", + "type": "string" + }, + "documentationUrl": { + "description": "A URL to further documentation regarding this service.", + "type": "string" + }, + "level": { + "description": "Service status levels as human and machine readable values.", + "enum": [ + "available", + "degraded", + "unavailable", + "critical" + ], + "type": "string" + }, + "meta": { + "additionalProperties": {}, + "description": "An unstructured set of extra metadata about this service.", + "type": "object" + }, + "summary": { + "description": "A human readable summary of the service status.", + "type": "string" + } + }, + "required": [ + "level", + "summary", + "meta" + ], + "type": "object" + }, + "savedObjects": { + "additionalProperties": false, + "properties": { + "detail": { + "description": "Human readable detail of the service status.", + "type": "string" + }, + "documentationUrl": { + "description": "A URL to further documentation regarding this service.", + "type": "string" + }, + "level": { + "description": "Service status levels as human and machine readable values.", + "enum": [ + "available", + "degraded", + "unavailable", + "critical" + ], + "type": "string" + }, + "meta": { + "additionalProperties": {}, + "description": "An unstructured set of extra metadata about this service.", + "type": "object" + }, + "summary": { + "description": "A human readable summary of the service status.", + "type": "string" + } + }, + "required": [ + "level", + "summary", + "meta" + ], + "type": "object" + } + }, + "required": [ + "elasticsearch", + "savedObjects" + ], + "type": "object" + }, + "overall": { + "additionalProperties": false, + "properties": { + "detail": { + "description": "Human readable detail of the service status.", + "type": "string" + }, + "documentationUrl": { + "description": "A URL to further documentation regarding this service.", + "type": "string" + }, + "level": { + "description": "Service status levels as human and machine readable values.", + "enum": [ + "available", + "degraded", + "unavailable", + "critical" + ], + "type": "string" + }, + "meta": { + "additionalProperties": {}, + "description": "An unstructured set of extra metadata about this service.", + "type": "object" + }, + "summary": { + "description": "A human readable summary of the service status.", + "type": "string" + } + }, + "required": [ + "level", + "summary", + "meta" + ], + "type": "object" + }, + "plugins": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "detail": { + "description": "Human readable detail of the service status.", + "type": "string" + }, + "documentationUrl": { + "description": "A URL to further documentation regarding this service.", + "type": "string" + }, + "level": { + "description": "Service status levels as human and machine readable values.", + "enum": [ + "available", + "degraded", + "unavailable", + "critical" + ], + "type": "string" + }, + "meta": { + "additionalProperties": {}, + "description": "An unstructured set of extra metadata about this service.", + "type": "object" + }, + "summary": { + "description": "A human readable summary of the service status.", + "type": "string" + } + }, + "required": [ + "level", + "summary", + "meta" + ], + "type": "object" + }, + "description": "A dynamic mapping of plugin ID to plugin status.", + "type": "object" + } + }, + "required": [ + "overall", + "core", + "plugins" + ], + "type": "object" + }, + "uuid": { + "description": "Unique, generated Kibana instance UUID. This UUID should persist even if the Kibana process restarts.", + "type": "string" + }, + "version": { + "additionalProperties": false, + "properties": { + "build_date": { + "description": "The date and time of this build.", + "type": "string" + }, + "build_flavor": { + "description": "The build flavour determines configuration and behavior of Kibana. On premise users will almost always run the \"traditional\" flavour, while other flavours are reserved for Elastic-specific use cases.", + "enum": [ + "serverless", + "traditional" + ], + "type": "string" + }, + "build_hash": { + "description": "A unique hash value representing the git commit of this Kibana build.", + "type": "string" + }, + "build_number": { + "description": "A monotonically increasing number, each subsequent build will have a higher number.", + "type": "number" + }, + "build_snapshot": { + "description": "Whether this build is a snapshot build.", + "type": "boolean" + }, + "number": { + "description": "A semantic version number.", + "type": "string" + } + }, + "required": [ + "number", + "build_hash", + "build_number", + "build_snapshot", + "build_flavor", + "build_date" + ], + "type": "object" + } + }, + "required": [ + "name", + "uuid", + "version", + "status", + "metrics" + ], + "type": "object" + } + }, "securitySchemes": { "apiKeyAuth": { "in": "header", @@ -18,7 +381,102844 @@ "version": "0.0.0" }, "openapi": "3.0.0", - "paths": {}, + "paths": { + "/api/actions/connector/_oauth_callback": { + "get": { + "operationId": "get-actions-connector-oauth-callback", + "parameters": [ + { + "in": "query", + "name": "code", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "state", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "error", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "error_description", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "session_state", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": {}, + "summary": "", + "tags": [] + } + }, + "/api/actions/connector/{id}": { + "delete": { + "description": "WARNING: When you delete a connector, it cannot be recovered.", + "operationId": "delete-actions-connector-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "An identifier for the connector.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "403": { + "description": "Indicates that this call is forbidden." + } + }, + "summary": "Delete a connector", + "tags": [ + "connectors" + ] + }, + "get": { + "operationId": "get-actions-connector-id", + "parameters": [ + { + "description": "An identifier for the connector.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": {}, + "type": "object" + }, + "connector_type_id": { + "description": "The connector type identifier.", + "type": "string" + }, + "id": { + "description": "The identifier for the connector.", + "type": "string" + }, + "is_connector_type_deprecated": { + "description": "Indicates whether the connector type is deprecated.", + "type": "boolean" + }, + "is_deprecated": { + "description": "Indicates whether the connector is deprecated.", + "type": "boolean" + }, + "is_missing_secrets": { + "description": "Indicates whether the connector is missing secrets.", + "type": "boolean" + }, + "is_preconfigured": { + "description": "Indicates whether the connector is preconfigured. If true, the `config` and `is_missing_secrets` properties are omitted from the response. ", + "type": "boolean" + }, + "is_system_action": { + "description": "Indicates whether the connector is used for system actions.", + "type": "boolean" + }, + "name": { + "description": " The name of the connector.", + "type": "string" + } + }, + "required": [ + "id", + "name", + "connector_type_id", + "is_preconfigured", + "is_deprecated", + "is_system_action", + "is_connector_type_deprecated" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "403": { + "description": "Indicates that this call is forbidden." + } + }, + "summary": "Get connector information", + "tags": [ + "connectors" + ] + }, + "post": { + "operationId": "post-actions-connector-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "An identifier for the connector.", + "in": "path", + "name": "id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": {}, + "default": {}, + "type": "object" + }, + "connector_type_id": { + "description": "The type of connector.", + "type": "string" + }, + "name": { + "description": "The display name for the connector.", + "type": "string" + }, + "secrets": { + "additionalProperties": {}, + "default": {}, + "type": "object" + } + }, + "required": [ + "name", + "connector_type_id" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": {}, + "type": "object" + }, + "connector_type_id": { + "description": "The connector type identifier.", + "type": "string" + }, + "id": { + "description": "The identifier for the connector.", + "type": "string" + }, + "is_connector_type_deprecated": { + "description": "Indicates whether the connector type is deprecated.", + "type": "boolean" + }, + "is_deprecated": { + "description": "Indicates whether the connector is deprecated.", + "type": "boolean" + }, + "is_missing_secrets": { + "description": "Indicates whether the connector is missing secrets.", + "type": "boolean" + }, + "is_preconfigured": { + "description": "Indicates whether the connector is preconfigured. If true, the `config` and `is_missing_secrets` properties are omitted from the response. ", + "type": "boolean" + }, + "is_system_action": { + "description": "Indicates whether the connector is used for system actions.", + "type": "boolean" + }, + "name": { + "description": " The name of the connector.", + "type": "string" + } + }, + "required": [ + "id", + "name", + "connector_type_id", + "is_preconfigured", + "is_deprecated", + "is_system_action", + "is_connector_type_deprecated" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "403": { + "description": "Indicates that this call is forbidden." + } + }, + "summary": "Create a connector", + "tags": [ + "connectors" + ] + }, + "put": { + "operationId": "put-actions-connector-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "An identifier for the connector.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": {}, + "default": {}, + "type": "object" + }, + "name": { + "description": "The display name for the connector.", + "type": "string" + }, + "secrets": { + "additionalProperties": {}, + "default": {}, + "type": "object" + } + }, + "required": [ + "name" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": {}, + "type": "object" + }, + "connector_type_id": { + "description": "The connector type identifier.", + "type": "string" + }, + "id": { + "description": "The identifier for the connector.", + "type": "string" + }, + "is_connector_type_deprecated": { + "description": "Indicates whether the connector type is deprecated.", + "type": "boolean" + }, + "is_deprecated": { + "description": "Indicates whether the connector is deprecated.", + "type": "boolean" + }, + "is_missing_secrets": { + "description": "Indicates whether the connector is missing secrets.", + "type": "boolean" + }, + "is_preconfigured": { + "description": "Indicates whether the connector is preconfigured. If true, the `config` and `is_missing_secrets` properties are omitted from the response. ", + "type": "boolean" + }, + "is_system_action": { + "description": "Indicates whether the connector is used for system actions.", + "type": "boolean" + }, + "name": { + "description": " The name of the connector.", + "type": "string" + } + }, + "required": [ + "id", + "name", + "connector_type_id", + "is_preconfigured", + "is_deprecated", + "is_system_action", + "is_connector_type_deprecated" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "403": { + "description": "Indicates that this call is forbidden." + } + }, + "summary": "Update a connector", + "tags": [ + "connectors" + ] + } + }, + "/api/actions/connector/{id}/_execute": { + "post": { + "description": "You can use this API to test an action that involves interaction with Kibana services or integrations with third-party systems.", + "operationId": "post-actions-connector-id-execute", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "An identifier for the connector.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "params": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "params" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": {}, + "type": "object" + }, + "connector_type_id": { + "description": "The connector type identifier.", + "type": "string" + }, + "id": { + "description": "The identifier for the connector.", + "type": "string" + }, + "is_connector_type_deprecated": { + "description": "Indicates whether the connector type is deprecated.", + "type": "boolean" + }, + "is_deprecated": { + "description": "Indicates whether the connector is deprecated.", + "type": "boolean" + }, + "is_missing_secrets": { + "description": "Indicates whether the connector is missing secrets.", + "type": "boolean" + }, + "is_preconfigured": { + "description": "Indicates whether the connector is preconfigured. If true, the `config` and `is_missing_secrets` properties are omitted from the response. ", + "type": "boolean" + }, + "is_system_action": { + "description": "Indicates whether the connector is used for system actions.", + "type": "boolean" + }, + "name": { + "description": " The name of the connector.", + "type": "string" + } + }, + "required": [ + "id", + "name", + "connector_type_id", + "is_preconfigured", + "is_deprecated", + "is_system_action", + "is_connector_type_deprecated" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "403": { + "description": "Indicates that this call is forbidden." + } + }, + "summary": "Run a connector", + "tags": [ + "connectors" + ] + } + }, + "/api/actions/connector_types": { + "get": { + "description": "You do not need any Kibana feature privileges to run this API.", + "operationId": "get-actions-connector-types", + "parameters": [ + { + "description": "A filter to limit the retrieved connector types to those that support a specific feature (such as alerting or cases).", + "in": "query", + "name": "feature_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "additionalProperties": false, + "properties": { + "allow_multiple_system_actions": { + "description": "Indicates whether multiple instances of the same system action connector can be used in a single rule.", + "type": "boolean" + }, + "enabled": { + "description": "Indicates whether the connector is enabled.", + "type": "boolean" + }, + "enabled_in_config": { + "description": "Indicates whether the connector is enabled in the Kibana configuration.", + "type": "boolean" + }, + "enabled_in_license": { + "description": "Indicates whether the connector is enabled through the license.", + "type": "boolean" + }, + "id": { + "description": "The identifier for the connector.", + "type": "string" + }, + "is_deprecated": { + "description": "Indicates whether the connector type is deprecated.", + "type": "boolean" + }, + "is_system_action_type": { + "description": "Indicates whether the action is a system action.", + "type": "boolean" + }, + "minimum_license_required": { + "description": "The minimum license required to enable the connector.", + "enum": [ + "basic", + "standard", + "gold", + "platinum", + "enterprise", + "trial" + ], + "type": "string" + }, + "name": { + "description": "The name of the connector type.", + "type": "string" + }, + "source": { + "description": "The source of the connector type definition.", + "enum": [ + "yml", + "spec", + "stack" + ], + "type": "string" + }, + "sub_feature": { + "description": "Indicates the sub-feature type the connector is grouped under.", + "enum": [ + "endpointSecurity" + ], + "type": "string" + }, + "supported_feature_ids": { + "description": "The list of supported features", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "id", + "name", + "enabled", + "enabled_in_config", + "enabled_in_license", + "minimum_license_required", + "supported_feature_ids", + "is_system_action_type", + "is_deprecated", + "source" + ], + "type": "object" + }, + "type": "array" + } + } + }, + "description": "Indicates a successful call." + }, + "403": { + "description": "Indicates that this call is forbidden." + } + }, + "summary": "Get connector types", + "tags": [ + "connectors" + ] + } + }, + "/api/actions/connectors": { + "get": { + "operationId": "get-actions-connectors", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": {}, + "type": "object" + }, + "connector_type_id": { + "description": "The connector type identifier.", + "type": "string" + }, + "id": { + "description": "The identifier for the connector.", + "type": "string" + }, + "is_connector_type_deprecated": { + "description": "Indicates whether the connector type is deprecated.", + "type": "boolean" + }, + "is_deprecated": { + "description": "Indicates whether the connector is deprecated.", + "type": "boolean" + }, + "is_missing_secrets": { + "description": "Indicates whether the connector is missing secrets.", + "type": "boolean" + }, + "is_preconfigured": { + "description": "Indicates whether the connector is preconfigured. If true, the `config` and `is_missing_secrets` properties are omitted from the response. ", + "type": "boolean" + }, + "is_system_action": { + "description": "Indicates whether the connector is used for system actions.", + "type": "boolean" + }, + "name": { + "description": " The name of the connector.", + "type": "string" + }, + "referenced_by_count": { + "description": "The number of saved objects that reference the connector. If is_preconfigured is true, this value is not calculated.", + "type": "number" + } + }, + "required": [ + "id", + "name", + "connector_type_id", + "is_preconfigured", + "is_deprecated", + "is_system_action", + "is_connector_type_deprecated", + "referenced_by_count" + ], + "type": "object" + }, + "type": "array" + } + } + }, + "description": "Indicates a successful call." + }, + "403": { + "description": "Indicates that this call is forbidden." + } + }, + "summary": "Get all connectors", + "tags": [ + "connectors" + ] + } + }, + "/api/agent_builder/a2a/{agentId}": { + "post": { + "description": "> warn\n> This endpoint is designed for A2A protocol clients and should not be used directly via REST APIs. Use an A2A SDK or A2A Inspector instead.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "post-agent-builder-a2a-agentid", + "parameters": [ + { + "description": "The unique identifier of the agent to send the A2A task to.", + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "a2aTaskRequestExample": { + "description": "WARNING: DO NOT USE THIS ENDPOINT VIA REST API. These examples are auto-generated and should not be run. Integrate with A2A using an A2A SDK or A2A Inspector instead.", + "value": { + "id": "task-123", + "jsonrpc": "2.0", + "method": "complete", + "params": { + "messages": [ + { + "content": "Hello from A2A protocol", + "role": "user" + } + ] + } + } + } + }, + "schema": {} + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "a2aTaskResponseExample": { + "description": "Example response from A2A Task Endpoint with results of task execution", + "value": { + "id": "task-123", + "jsonrpc": "2.0", + "result": { + "conversation_id": "conv-456", + "response": { + "message": "Hello! How can I help you today?" + }, + "type": "response" + } + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Send A2A task", + "tags": [ + "agent builder" + ], + "x-state": "Technical Preview; added in 9.2.0" + } + }, + "/api/agent_builder/a2a/{agentId}.json": { + "get": { + "description": "Get agent discovery metadata in JSON format. Use this endpoint to provide agent information for A2A protocol integration and discovery.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "get-agent-builder-a2a-agentid.json", + "parameters": [ + { + "description": "The unique identifier of the agent to get A2A metadata for.", + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "a2aAgentCardResponseExample": { + "description": "Example response card of Elastic AI Agent", + "value": { + "capabilities": { + "pushNotifications": false, + "stateTransitionHistory": false, + "streaming": false + }, + "defaultInputModes": [ + "text/plain" + ], + "defaultOutputModes": [ + "text/plain" + ], + "description": "Elastic AI Agent", + "name": "Elastic AI Agent", + "protocolVersion": "0.3.0", + "provider": { + "organization": "Elastic", + "url": "https://elastic.co" + }, + "securitySchemes": { + "authorization": { + "description": "Authentication token", + "in": "header", + "name": "Authorization", + "type": "apiKey" + } + }, + "skills": [ + { + "description": "A powerful tool for searching and analyzing data within your Elasticsearch cluster.", + "examples": [], + "id": "platform.core.search", + "inputModes": [ + "text/plain", + "application/json" + ], + "name": "platform.core.search", + "outputModes": [ + "text/plain", + "application/json" + ], + "tags": [ + "tool" + ] + } + ], + "supportsAuthenticatedExtendedCard": false, + "url": "http://localhost:5601/api/agent_builder/a2a/elastic-ai-agent", + "version": "0.1.0" + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Get A2A agent card", + "tags": [ + "agent builder" + ], + "x-state": "Technical Preview; added in 9.2.0" + } + }, + "/api/agent_builder/agents": { + "get": { + "description": "List all available agents. Use this endpoint to retrieve complete agent information including their current configuration and assigned tools.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "get-agent-builder-agents", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "listAgentsResponseExample": { + "description": "Example response that returns one built-in Elastic agent and one created by the user", + "value": { + "results": [ + { + "configuration": { + "tools": [ + { + "tool_ids": [ + "platform.core.search", + "platform.core.list_indices", + "platform.core.get_index_mapping", + "platform.core.get_document_by_id" + ] + } + ] + }, + "description": "Elastic AI Agent", + "id": "elastic-ai-agent", + "name": "Elastic AI Agent", + "type": "chat" + }, + { + "avatar_color": "#BFDBFF", + "avatar_symbol": "SI", + "configuration": { + "instructions": "You are a custom agent that wants to help searching data using all indices starting with prefix \"content-\".", + "tools": [ + { + "tool_ids": [ + "platform.core.search", + "platform.core.list_indices", + "platform.core.get_index_mapping", + "platform.core.get_document_by_id" + ] + } + ] + }, + "description": "Hi! I can help you search the data within the indices starting with \"content-\" prefix.", + "id": "created-agent-id", + "labels": [ + "custom-indices", + "department-search" + ], + "name": "Search Index Helper", + "type": "chat" + } + ] + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "List agents", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + }, + "post": { + "description": "Create a new agent. Use this endpoint to define the agent's behavior, appearance, and capabilities through comprehensive configuration options.

[Required authorization] Route required privileges: manage_agent_builder.", + "operationId": "post-agent-builder-agents", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "createAgentRequestExample": { + "description": "Example request for creating a custom agent with special prompt and tools", + "value": { + "avatar_color": "#BFDBFF", + "avatar_symbol": "SI", + "configuration": { + "instructions": "You are a custom agent that wants to help searching data using all indices starting with prefix \"content-\".", + "tools": [ + { + "tool_ids": [ + "platform.core.search", + "platform.core.list_indices", + "platform.core.get_index_mapping", + "platform.core.get_document_by_id" + ] + } + ] + }, + "description": "Hi! I can help you search the data within the indices starting with \"content-\" prefix.", + "id": "created-agent-id", + "labels": [ + "custom-indices", + "department-search" + ], + "name": "Search Index Helper" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "avatar_color": { + "description": "Optional hex color code for the agent avatar.", + "type": "string" + }, + "avatar_symbol": { + "description": "Optional symbol/initials for the agent avatar.", + "type": "string" + }, + "configuration": { + "additionalProperties": false, + "description": "Configuration settings for the agent.", + "properties": { + "instructions": { + "description": "Optional system instructions that define the agent behavior.", + "type": "string" + }, + "tools": { + "items": { + "additionalProperties": false, + "description": "Tool selection configuration for the agent.", + "properties": { + "tool_ids": { + "description": "Array of tool IDs that the agent can use.", + "items": { + "description": "Tool ID to be available to the agent.", + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "tool_ids" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "tools" + ], + "type": "object" + }, + "description": { + "description": "Description of what the agent does.", + "type": "string" + }, + "id": { + "description": "Unique identifier for the agent.", + "type": "string" + }, + "labels": { + "description": "Optional labels for categorizing and organizing agents.", + "items": { + "description": "Label for categorizing the agent.", + "type": "string" + }, + "type": "array" + }, + "name": { + "description": "Display name for the agent.", + "type": "string" + } + }, + "required": [ + "id", + "name", + "description", + "configuration" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "createAgentResponseExample": { + "description": "Example response returning the definition of an agent created as a result of the request", + "value": { + "avatar_color": "#BFDBFF", + "avatar_symbol": "SI", + "configuration": { + "instructions": "You are a custom agent that wants to help searching data using all indices starting with prefix \"content-\".", + "tools": [ + { + "tool_ids": [ + "platform.core.search", + "platform.core.list_indices", + "platform.core.get_index_mapping", + "platform.core.get_document_by_id" + ] + } + ] + }, + "description": "Hi! I can help you search the data within the indices starting with \"content-\" prefix.", + "id": "created-agent-id", + "labels": [ + "custom-indices", + "department-search" + ], + "name": "Search Index Helper", + "type": "chat" + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Create an agent", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + } + }, + "/api/agent_builder/agents/{id}": { + "delete": { + "description": "Delete an agent by ID. This action cannot be undone.

[Required authorization] Route required privileges: manage_agent_builder.", + "operationId": "delete-agent-builder-agents-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the agent to delete.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "deleteAgentResponseExample": { + "description": "Example response showing that deletion of the agent has been successful", + "value": { + "success": true + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Delete an agent", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + }, + "get": { + "description": "Get a specific agent by ID. Use this endpoint to retrieve the complete agent definition including all configuration details and tool assignments.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "get-agent-builder-agents-id", + "parameters": [ + { + "description": "The unique identifier of the agent to retrieve.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "getAgentByIdResponseExample": { + "description": "Example response that an agent created by the user that will query elasticsearch indices starting with 'content-' prefix to answer the questions.", + "value": { + "avatar_color": "#BFDBFF", + "avatar_symbol": "SI", + "configuration": { + "instructions": "You are a custom agent that wants to help searching data using all indices starting with prefix \"content-\".", + "tools": [ + { + "tool_ids": [ + "platform.core.search", + "platform.core.list_indices", + "platform.core.get_index_mapping", + "platform.core.get_document_by_id" + ] + } + ] + }, + "description": "Hi! I can help you search the data within the indices starting with \"content-\" prefix.", + "id": "created-agent-id", + "labels": [ + "custom-indices", + "department-search" + ], + "name": "Search Index Helper", + "type": "chat" + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Get an agent by ID", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + }, + "put": { + "description": "Update an existing agent configuration. Use this endpoint to modify any aspect of the agent's behavior, appearance, or capabilities.

[Required authorization] Route required privileges: manage_agent_builder.", + "operationId": "put-agent-builder-agents-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the agent to update.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "createAgentRequestExample": { + "description": "Example request for updating custom agent", + "value": { + "avatar_color": "#BFDBFF", + "avatar_symbol": "SI", + "configuration": { + "instructions": "You are a custom agent that wants to help searching data using all indices starting with prefix \"content-\".", + "tools": [ + { + "tool_ids": [ + "platform.core.search", + "platform.core.list_indices", + "platform.core.get_index_mapping", + "platform.core.get_document_by_id" + ] + } + ] + }, + "description": "Updated description - Search for anything in \"content-*\" indices!", + "id": "created-agent-id", + "labels": [ + "custom-indices", + "department-search", + "elastic-employees" + ], + "name": "Search Index Helper" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "avatar_color": { + "description": "Updated hex color code for the agent avatar.", + "type": "string" + }, + "avatar_symbol": { + "description": "Updated symbol/initials for the agent avatar.", + "type": "string" + }, + "configuration": { + "additionalProperties": false, + "description": "Updated configuration settings for the agent.", + "properties": { + "instructions": { + "description": "Updated system instructions that define the agent behavior.", + "type": "string" + }, + "tools": { + "items": { + "additionalProperties": false, + "description": "Tool selection configuration for the agent.", + "properties": { + "tool_ids": { + "description": "Array of tool IDs that the agent can use.", + "items": { + "description": "Tool ID to be available to the agent.", + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "tool_ids" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "description": { + "description": "Updated description of what the agent does.", + "type": "string" + }, + "labels": { + "description": "Updated labels for categorizing and organizing agents.", + "items": { + "description": "Updated label for categorizing the agent.", + "type": "string" + }, + "type": "array" + }, + "name": { + "description": "Updated display name for the agent.", + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "updateAgentResponseExample": { + "description": "Example response returning the agent definition with the changes applied from the request", + "value": { + "avatar_color": "#BFDBFF", + "avatar_symbol": "SI", + "configuration": { + "instructions": "You are a custom agent that wants to help searching data using all indices starting with prefix \"content-\".", + "tools": [ + { + "tool_ids": [ + "platform.core.search", + "platform.core.list_indices", + "platform.core.get_index_mapping", + "platform.core.get_document_by_id" + ] + } + ] + }, + "description": "Updated description - Search for anything in \"content-*\" indices!", + "id": "created-agent-id", + "labels": [ + "custom-indices", + "department-search", + "elastic-employees" + ], + "name": "Search Index Helper", + "type": "chat" + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Update an agent", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + } + }, + "/api/agent_builder/conversations": { + "get": { + "description": "List all conversations for a user. Use the optional agent ID to filter conversations by a specific agent.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "get-agent-builder-conversations", + "parameters": [ + { + "description": "Optional agent ID to filter conversations by a specific agent.", + "in": "query", + "name": "agent_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "listConversationsResponseExample": { + "description": "Example response containing the list of conversations with all agents", + "value": { + "results": [ + { + "agent_id": "elastic-ai-agent", + "created_at": "2025-09-19T17:45:39.554Z", + "id": "bcc176c5-38f6-40be-be0c-898e34fa1480", + "title": "General Greeting", + "updated_at": "2025-09-19T17:45:39.554Z", + "user": { + "username": "elastic" + } + } + ] + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "List conversations", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + } + }, + "/api/agent_builder/conversations/{conversation_id}": { + "delete": { + "description": "Delete a conversation by ID. This action cannot be undone.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "delete-agent-builder-conversations-conversation-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the conversation to delete.", + "in": "path", + "name": "conversation_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "deleteConversationResponseExample": { + "description": "Example response showing that deletion of conversation has been successful", + "value": { + "success": true + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Delete conversation by ID", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + }, + "get": { + "description": "Get a specific conversation by ID. Use this endpoint to retrieve the complete conversation history including all messages and metadata.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "get-agent-builder-conversations-conversation-id", + "parameters": [ + { + "description": "The unique identifier of the conversation to retrieve.", + "in": "path", + "name": "conversation_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "getConversationByIdResponseExample": { + "description": "Example response containing the contents of a convesation with the chat agent", + "value": { + "agent_id": "elastic-ai-agent", + "created_at": "2025-09-19T17:45:39.554Z", + "id": "bcc176c5-38f6-40be-be0c-898e34fa1480", + "rounds": [ + { + "id": "170ec3b2-0f5a-4538-8b60-549572386d2a", + "input": { + "message": "Hello, how are you?" + }, + "response": { + "message": "Since this is a general greeting that doesn't require any organizational or product-specific information, I can respond without using tools.\n\nHello! I'm doing well, thank you for asking. I'm here to help you with any questions you may have. How can I assist you today?" + }, + "steps": [] + } + ], + "title": "General Greeting", + "updated_at": "2025-09-19T17:45:39.554Z", + "user": { + "username": "elastic" + } + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Get conversation by ID", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + } + }, + "/api/agent_builder/conversations/{conversation_id}/attachments": { + "get": { + "description": "List all attachments for a conversation. Use the optional include_deleted query parameter to include soft-deleted attachments.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "get-agent-builder-conversations-conversation-id-attachments", + "parameters": [ + { + "description": "The unique identifier of the conversation.", + "in": "path", + "name": "conversation_id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Whether to include deleted attachments in the list.", + "in": "query", + "name": "include_deleted", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "listAttachmentsResponseExample": { + "description": "Example response containing active attachments for a conversation", + "value": { + "results": [ + { + "active": true, + "current_version": 2, + "description": "My text file", + "id": "attachment-1", + "type": "text", + "versions": [ + { + "content_hash": "abc123", + "created_at": "2025-01-01T10:00:00.000Z", + "data": "Initial content", + "estimated_tokens": 3, + "version": 1 + }, + { + "content_hash": "def456", + "created_at": "2025-01-01T11:00:00.000Z", + "data": "Updated content", + "estimated_tokens": 3, + "version": 2 + } + ] + }, + { + "active": true, + "current_version": 1, + "description": "Configuration data", + "id": "attachment-2", + "type": "json", + "versions": [ + { + "content_hash": "ghi789", + "created_at": "2025-01-01T12:00:00.000Z", + "data": { + "key": "value", + "nested": { + "field": 123 + } + }, + "estimated_tokens": 15, + "version": 1 + } + ] + } + ], + "total_token_estimate": 21 + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "List conversation attachments", + "tags": [ + "agent builder" + ], + "x-state": "Technical Preview; added in 9.2.0" + }, + "post": { + "description": "Create a new attachment for a conversation with version tracking.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "post-agent-builder-conversations-conversation-id-attachments", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the conversation.", + "in": "path", + "name": "conversation_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "createHiddenAttachmentExample": { + "description": "Example request for creating a hidden attachment", + "value": { + "data": "Internal system data", + "description": "System context", + "hidden": true, + "type": "text" + } + }, + "createJsonAttachmentExample": { + "description": "Example request for creating a JSON attachment with custom ID", + "value": { + "data": { + "configuration": { + "enabled": true, + "threshold": 50 + }, + "metadata": { + "source": "user_input" + } + }, + "description": "Application settings", + "id": "custom-attachment-id", + "type": "json" + } + }, + "createTextAttachmentExample": { + "description": "Example request for creating a text attachment", + "value": { + "data": "This is the content of my text attachment", + "description": "Meeting notes", + "type": "text" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "data": {}, + "description": { + "description": "Human-readable description of the attachment.", + "type": "string" + }, + "hidden": { + "description": "Whether the attachment should be hidden from the user.", + "type": "boolean" + }, + "id": { + "description": "Optional custom ID for the attachment.", + "type": "string" + }, + "type": { + "description": "The type of the attachment (e.g., text, json, visualization_ref).", + "type": "string" + } + }, + "required": [ + "type", + "data" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "createAttachmentResponseExample": { + "description": "Example response returning the created attachment", + "value": { + "attachment": { + "active": true, + "current_version": 1, + "description": "Meeting notes", + "id": "att-abc123", + "type": "text", + "versions": [ + { + "content_hash": "sha256-xyz", + "created_at": "2025-01-06T10:00:00.000Z", + "data": "This is the content of my text attachment", + "estimated_tokens": 12, + "version": 1 + } + ] + } + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Create conversation attachment", + "tags": [ + "agent builder" + ], + "x-state": "Technical Preview; added in 9.2.0" + } + }, + "/api/agent_builder/conversations/{conversation_id}/attachments/{attachment_id}": { + "delete": { + "description": "Delete an attachment. By default performs a soft delete (can be restored). Use permanent=true to permanently remove unreferenced attachments.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "delete-agent-builder-conversations-conversation-id-attachments-attachment-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the conversation.", + "in": "path", + "name": "conversation_id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "The unique identifier of the attachment to delete.", + "in": "path", + "name": "attachment_id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "If true, permanently removes the attachment (only for unreferenced attachments).", + "in": "query", + "name": "permanent", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "permanentDeleteAttachmentResponseExample": { + "description": "Example response for permanent delete (cannot be restored)", + "value": { + "permanent": true, + "success": true + } + }, + "softDeleteAttachmentResponseExample": { + "description": "Example response for soft delete (can be restored)", + "value": { + "permanent": false, + "success": true + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Delete conversation attachment", + "tags": [ + "agent builder" + ], + "x-state": "Technical Preview; added in 9.2.0" + }, + "patch": { + "description": "Rename an attachment without creating a new version.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "patch-agent-builder-conversations-conversation-id-attachments-attachment-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the conversation.", + "in": "path", + "name": "conversation_id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "The unique identifier of the attachment to rename.", + "in": "path", + "name": "attachment_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "renameAttachmentExample": { + "description": "Example request for renaming an attachment", + "value": { + "description": "Updated attachment name" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "description": { + "description": "The new description/name for the attachment.", + "type": "string" + } + }, + "required": [ + "description" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "renameAttachmentResponseExample": { + "description": "Example response returning the renamed attachment (version unchanged)", + "value": { + "attachment": { + "active": true, + "current_version": 1, + "description": "Updated attachment name", + "id": "att-abc123", + "type": "text", + "versions": [ + { + "content_hash": "sha256-xyz", + "created_at": "2025-01-06T10:00:00.000Z", + "data": "Content remains the same", + "estimated_tokens": 10, + "version": 1 + } + ] + }, + "success": true + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Rename attachment", + "tags": [ + "agent builder" + ], + "x-state": "Technical Preview; added in 9.2.0" + }, + "put": { + "description": "Update an attachment content. Creates a new version if content changed.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "put-agent-builder-conversations-conversation-id-attachments-attachment-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the conversation.", + "in": "path", + "name": "conversation_id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "The unique identifier of the attachment to update.", + "in": "path", + "name": "attachment_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "updateAttachmentContentExample": { + "description": "Example request for updating attachment content", + "value": { + "data": "This is the updated content" + } + }, + "updateAttachmentWithDescriptionExample": { + "description": "Example request for updating both content and description", + "value": { + "data": "New content version", + "description": "Updated meeting notes - v2" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "data": {}, + "description": { + "description": "Optional new description for the attachment.", + "type": "string" + } + }, + "required": [ + "data" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "updateAttachmentResponseExample": { + "description": "Example response returning the updated attachment with new version", + "value": { + "attachment": { + "active": true, + "current_version": 2, + "description": "Meeting notes", + "id": "att-abc123", + "type": "text", + "versions": [ + { + "content_hash": "sha256-abc", + "created_at": "2025-01-06T10:00:00.000Z", + "data": "Original content", + "estimated_tokens": 10, + "version": 1 + }, + { + "content_hash": "sha256-def", + "created_at": "2025-01-06T11:00:00.000Z", + "data": "This is the updated content", + "estimated_tokens": 12, + "version": 2 + } + ] + }, + "new_version": 2 + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Update conversation attachment", + "tags": [ + "agent builder" + ], + "x-state": "Technical Preview; added in 9.2.0" + } + }, + "/api/agent_builder/conversations/{conversation_id}/attachments/{attachment_id}/_restore": { + "post": { + "description": "Restore a soft-deleted attachment.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "post-agent-builder-conversations-conversation-id-attachments-attachment-id-restore", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the conversation.", + "in": "path", + "name": "conversation_id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "The unique identifier of the attachment to restore.", + "in": "path", + "name": "attachment_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "restoreAttachmentResponseExample": { + "description": "Example response returning the restored attachment", + "value": { + "attachment": { + "active": true, + "current_version": 1, + "description": "Restored attachment", + "id": "att-abc123", + "type": "text", + "versions": [ + { + "content_hash": "sha256-xyz", + "created_at": "2025-01-06T10:00:00.000Z", + "data": "Restored content", + "estimated_tokens": 10, + "version": 1 + } + ] + }, + "success": true + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Restore deleted attachment", + "tags": [ + "agent builder" + ], + "x-state": "Technical Preview; added in 9.2.0" + } + }, + "/api/agent_builder/converse": { + "post": { + "description": "Send a message to an agent and receive a complete response. This synchronous endpoint waits for the agent to fully process your request before returning the final result. Use this for simple chat interactions where you need the complete response.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "post-agent-builder-converse", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "converseRequestExample": { + "description": "Example request to send a message to the agent as a part of the conversation", + "value": { + "agent_id": "elastic-ai-agent", + "connector_id": "my-connector-id", + "input": "What is Elasticsearch?" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "agent_id": { + "default": "elastic-ai-agent", + "description": "The ID of the agent to chat with. Defaults to the default Elastic AI agent.", + "type": "string" + }, + "attachments": { + "description": "**Technical Preview; added in 9.3.0.** Optional attachments to send with the message.", + "items": { + "additionalProperties": false, + "properties": { + "data": { + "additionalProperties": {}, + "description": "Payload of the attachment.", + "type": "object" + }, + "hidden": { + "description": "When true, the attachment will not be displayed in the UI.", + "type": "boolean" + }, + "id": { + "description": "Optional id for the attachment.", + "type": "string" + }, + "type": { + "description": "Type of the attachment.", + "type": "string" + } + }, + "required": [ + "type", + "data" + ], + "type": "object" + }, + "type": "array" + }, + "browser_api_tools": { + "description": "Optional browser API tools to be registered as LLM tools with browser.* namespace. These tools execute on the client side.", + "items": { + "additionalProperties": false, + "properties": { + "description": { + "description": "Description of what the browser API tool does.", + "type": "string" + }, + "id": { + "description": "Unique identifier for the browser API tool.", + "type": "string" + }, + "schema": {} + }, + "required": [ + "id", + "description", + "schema" + ], + "type": "object" + }, + "type": "array" + }, + "capabilities": { + "additionalProperties": false, + "description": "Controls agent capabilities during conversation. Currently supports visualization rendering for tabular tool results.", + "properties": { + "visualizations": { + "description": "When true, allows the agent to render tabular data from tool results as interactive visualizations using custom XML elements in responses.", + "type": "boolean" + } + }, + "type": "object" + }, + "connector_id": { + "description": "Optional connector ID for the agent to use for external integrations.", + "type": "string" + }, + "conversation_id": { + "description": "Optional existing conversation ID to continue a previous conversation.", + "type": "string" + }, + "input": { + "description": "The user input message to send to the agent.", + "type": "string" + }, + "prompts": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "allow": { + "type": "boolean" + } + }, + "required": [ + "allow" + ], + "type": "object" + }, + "description": "Can be used to respond to a confirmation prompt.", + "type": "object" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "converseResponseExample": { + "description": "Example response containing the chain of events representing a conversation with the agent", + "value": { + "conversation_id": "696ccd6d-4bff-4b26-a62e-522ccf2dcd16", + "response": { + "message": "Elasticsearch is a distributed, RESTful search and analytics engine capable of addressing a growing number of use cases. As the heart of the Elastic Stack, it centrally stores your data for lightning fast search, fine‑tuned relevancy, and powerful analytics that scale with ease." + }, + "steps": [ + { + "reasoning": "Searching for official documentation or content that explains what Elasticsearch is", + "type": "reasoning" + }, + { + "params": { + "query": "what is elasticsearch definition overview introduction" + }, + "progression": [ + { + "message": "Selecting the best target for this query" + } + ], + "results": [ + { + "data": { + "message": "Could not figure out which index to use" + }, + "type": "error" + } + ], + "tool_call_id": "tooluse_shOdUwKIRwC9YhqGzeg0cQ", + "tool_id": "platform.core.search", + "type": "tool_call" + } + ] + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Send chat message", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + } + }, + "/api/agent_builder/converse/async": { + "post": { + "description": "Send a message to an agent and receive real-time streaming events. This asynchronous endpoint provides live updates as the agent processes your request, allowing you to see intermediate steps and progress. Use this for interactive experiences where you want to monitor the agent's thinking process.\n\n## Event types\n\nThe endpoint emits Server-Sent Events (SSE) with the following custom event types:\n\n`conversation_id_set`\n\nSets the conversation ID.\n\nSchema:\n```json\n{\n \"conversation_id\": \"uuid\"\n}\n```\n\n---\n\n`conversation_created`\n\nFires when a new conversation is persisted and assigned an ID.\n\nSchema:\n```json\n{\n \"conversation_id\": \"uuid\",\n \"title\": \"conversation title\"\n}\n```\n\n---\n\n`conversation_updated`\n\nFires when a conversation is updated.\n\nSchema:\n```json\n{\n \"conversation_id\": \"uuid\",\n \"title\": \"updated conversation title\"\n}\n```\n\n---\n\n`reasoning`\n\nHandles reasoning-related data.\n\nSchema:\n```json\n{\n \"reasoning\": \"plain text reasoning content\",\n \"transient\": false\n}\n```\n\n---\n\n`tool_call`\n\nTriggers when a tool is invoked.\n\nSchema:\n```json\n{\n \"tool_call_id\": \"uuid\",\n \"tool_id\": \"tool_name\",\n \"params\": {}\n}\n```\n\n---\n\n`tool_progress`\n\nReports progress of a running tool.\n\nSchema:\n```json\n{\n \"tool_call_id\": \"uuid\",\n \"message\": \"progress message\"\n}\n```\n\n---\n\n`tool_result`\n\nReturns results from a completed tool call.\n\nSchema:\n```json\n{\n \"tool_call_id\": \"uuid\",\n \"tool_id\": \"tool_name\",\n \"results\": []\n}\n```\n\n**Note:** `results` is an array of `ToolResult` objects.\n\n---\n\n`message_chunk`\n\nStreams partial text chunks.\n\nSchema:\n```json\n{\n \"message_id\": \"uuid\",\n \"text_chunk\": \"partial text\"\n}\n```\n\n---\n\n`message_complete`\n\nIndicates message stream is finished.\n\nSchema:\n```json\n{\n \"message_id\": \"uuid\",\n \"message_content\": \"full text content of the message\"\n}\n```\n\n---\n\n`thinking_complete`\n\nMarks the end of the thinking/reasoning phase.\n\nSchema:\n```json\n{\n \"time_to_first_token\": 0\n}\n```\n\n**Note:** `time_to_first_token` is in milliseconds.\n\n---\n\n`round_complete`\n\nMarks end of one conversation round.\n\nSchema:\n```json\n{\n \"round\": {}\n}\n```\n\n**Note:** `round` contains the full round json object.\n\n---\n\n## Event flow\n\nA typical conversation round emits events in this sequence:\n\n1. `reasoning` (potentially multiple, some transient)\n2. `tool_call` (if tools are used)\n3. `tool_progress` (zero or more progress updates)\n4. `tool_result` (when tool completes)\n5. `thinking_complete`\n6. `message_chunk` (multiple, as text streams)\n7. `message_complete`\n8. `round_complete`\n\n

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "post-agent-builder-converse-async", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "converseAsyncRequestExample": { + "description": "Example request to send a message to the agent as a part of the conversation", + "value": { + "agent_id": "elastic-ai-agent", + "conversation_id": "c250305b-1929-4248-b568-b9e3f065fda5", + "input": "Hello" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "agent_id": { + "default": "elastic-ai-agent", + "description": "The ID of the agent to chat with. Defaults to the default Elastic AI agent.", + "type": "string" + }, + "attachments": { + "description": "**Technical Preview; added in 9.3.0.** Optional attachments to send with the message.", + "items": { + "additionalProperties": false, + "properties": { + "data": { + "additionalProperties": {}, + "description": "Payload of the attachment.", + "type": "object" + }, + "hidden": { + "description": "When true, the attachment will not be displayed in the UI.", + "type": "boolean" + }, + "id": { + "description": "Optional id for the attachment.", + "type": "string" + }, + "type": { + "description": "Type of the attachment.", + "type": "string" + } + }, + "required": [ + "type", + "data" + ], + "type": "object" + }, + "type": "array" + }, + "browser_api_tools": { + "description": "Optional browser API tools to be registered as LLM tools with browser.* namespace. These tools execute on the client side.", + "items": { + "additionalProperties": false, + "properties": { + "description": { + "description": "Description of what the browser API tool does.", + "type": "string" + }, + "id": { + "description": "Unique identifier for the browser API tool.", + "type": "string" + }, + "schema": {} + }, + "required": [ + "id", + "description", + "schema" + ], + "type": "object" + }, + "type": "array" + }, + "capabilities": { + "additionalProperties": false, + "description": "Controls agent capabilities during conversation. Currently supports visualization rendering for tabular tool results.", + "properties": { + "visualizations": { + "description": "When true, allows the agent to render tabular data from tool results as interactive visualizations using custom XML elements in responses.", + "type": "boolean" + } + }, + "type": "object" + }, + "connector_id": { + "description": "Optional connector ID for the agent to use for external integrations.", + "type": "string" + }, + "conversation_id": { + "description": "Optional existing conversation ID to continue a previous conversation.", + "type": "string" + }, + "input": { + "description": "The user input message to send to the agent.", + "type": "string" + }, + "prompts": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "allow": { + "type": "boolean" + } + }, + "required": [ + "allow" + ], + "type": "object" + }, + "description": "Can be used to respond to a confirmation prompt.", + "type": "object" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "text/event-stream": { + "examples": { + "converseAsyncResponseExample": { + "description": "Example stream containing the chain of events representing a conversation with the agent", + "value": [ + { + "data": { + "data": { + "conversation_id": "c250305b-1929-4248-b568-b9e3f065fda5" + } + }, + "event": "conversation_id_set" + }, + { + "data": { + "data": { + "reasoning": "Starting with a general search to understand what content is available." + } + }, + "event": "reasoning" + }, + { + "data": { + "data": { + "params": { + "query": "latest documents" + }, + "tool_call_id": "tooluse__2aJELgyRYqD8SDOKSiwtg", + "tool_id": "platform.core.search" + } + }, + "event": "tool_call" + }, + { + "data": { + "data": { + "results": [ + { + "data": { + "message": "Could not figure out which index to use" + }, + "type": "error" + } + ], + "tool_call_id": "tooluse__2aJELgyRYqD8SDOKSiwtg" + } + }, + "event": "tool_result" + }, + { + "data": { + "data": { + "round": { + "id": "a5692d54-bc06-4a6e-aea1-412779c73f66", + "input": { + "message": "Hello" + }, + "response": { + "message": "Hello! How can I help you today?" + } + } + } + }, + "event": "round_complete" + } + ] + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Send chat message (streaming)", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + } + }, + "/api/agent_builder/mcp": { + "post": { + "description": "> warn\n> This endpoint is designed for MCP clients (Claude Desktop, Cursor, VS Code, etc.) and should not be used directly via REST APIs. Use MCP Inspector or native MCP clients instead.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "post-agent-builder-mcp", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "examples": { + "mcpInitializeRequestExample": { + "description": "WARNING: DO NOT USE THIS ENDPOINT VIA REST API. These examples are auto-generated and should not be run. Integrate with MCP using MCP Inspector or native MCP clients (Claude Desktop, Cursor, VS Code) instead.", + "value": { + "id": 1, + "jsonrpc": "2.0", + "method": "initialize", + "params": { + "capabilities": {}, + "clientInfo": { + "name": "test-client", + "version": "1.0.0" + }, + "protocolVersion": "2024-11-05" + } + } + } + }, + "schema": {} + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "mcpInitializeResponseExample": { + "description": "Example response showing the successful result of communication initialisation over MCP protocol", + "value": { + "id": 1, + "jsonrpc": "2.0", + "result": { + "capabilities": { + "tools": { + "listChanged": true + } + }, + "protocolVersion": "2024-11-05", + "serverInfo": { + "name": "elastic-mcp-server", + "version": "0.0.1" + } + } + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "MCP server", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + } + }, + "/api/agent_builder/tools": { + "get": { + "description": "List all available tools. Use this endpoint to retrieve complete tool definitions including their schemas and configuration requirements.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "get-agent-builder-tools", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "listToolsResponseExample": { + "description": "Example response returning a list of existing tools", + "value": { + "results": [ + { + "configuration": {}, + "description": "A powerful tool for searching and analyzing data within your Elasticsearch cluster.\nIt supports both full-text relevance searches and structured analytical queries.\n\nUse this tool for any query that involves finding documents, counting, aggregating, or summarizing data from a known index.\n\nExamples of queries:\n- \"find articles about serverless architecture\"\n- \"search for support tickets mentioning 'billing issue' or 'refund request'\"\n- \"what is our policy on parental leave?\"\n- \"list all products where the category is 'electronics'\"\n- \"show me the last 5 documents from that index\"\n- \"show me the sales over the last year break down by month\"\n\nNote:\n- The 'index' parameter can be used to specify which index to search against.\n If not provided, the tool will decide itself which is the best index to use.\n- It is perfectly fine not to specify the 'index' parameter. It should only be specified when you already\n know about the index and fields you want to search on, e.g. if the user explicitly specified it.", + "id": "platform.core.search", + "readonly": true, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "index": { + "description": "(optional) Index to search against. If not provided, will automatically select the best index to use based on the query.", + "type": "string" + }, + "query": { + "description": "A natural language query expressing the search request", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "tags": [], + "type": "builtin" + }, + { + "configuration": {}, + "description": "Retrieve the full content (source) of an Elasticsearch document based on its ID and index name.", + "id": "platform.core.get_document_by_id", + "readonly": true, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "id": { + "description": "ID of the document to retrieve", + "type": "string" + }, + "index": { + "description": "Name of the index to retrieve the document from", + "type": "string" + } + }, + "required": [ + "id", + "index" + ], + "type": "object" + }, + "tags": [], + "type": "builtin" + }, + { + "configuration": {}, + "description": "Execute an ES|QL query and return the results in a tabular format.\n\n**IMPORTANT**: This tool only **runs** queries; it does not write them.\nThink of this as the final step after a query has been prepared.\n\nYou **must** get the query from one of two sources before calling this tool:\n1. The output of the `platform.core.generate_esql` tool (if the tool is available).\n2. A verbatim query provided directly by the user.\n\nUnder no circumstances should you invent, guess, or modify a query yourself for this tool.\nIf you need a query, use the `platform.core.generate_esql` tool first.", + "id": "platform.core.execute_esql", + "readonly": true, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "query": { + "description": "The ES|QL query to execute", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "tags": [], + "type": "builtin" + }, + { + "configuration": { + "params": { + "limit": { + "description": "Maximum number of results to return", + "type": "integer" + }, + "startTime": { + "description": "Start time for the analysis in ISO format", + "type": "date" + } + }, + "query": "FROM financial_trades | WHERE execution_timestamp >= ?startTime | STATS trade_count=COUNT(*), avg_price=AVG(execution_price) BY symbol | SORT trade_count DESC | LIMIT ?limit" + }, + "description": "Example ES|QL query tool for analyzing financial trades with time filtering", + "id": "example-esql-tool", + "readonly": false, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Parameters needed to execute the query", + "properties": { + "limit": { + "description": "Maximum number of results to return", + "type": "integer" + }, + "startTime": { + "description": "Start time for the analysis in ISO format", + "format": "date-time", + "type": "string" + } + }, + "required": [ + "startTime", + "limit" + ], + "type": "object" + }, + "tags": [ + "analytics", + "finance" + ], + "type": "esql" + }, + { + "configuration": { + "pattern": "financial_*" + }, + "description": "Search tool specifically for financial data analysis and reporting", + "id": "example-index-search-tool", + "readonly": false, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "nlQuery": { + "description": "A natural language query expressing the search request", + "type": "string" + } + }, + "required": [ + "nlQuery" + ], + "type": "object" + }, + "tags": [ + "search", + "finance" + ], + "type": "index_search" + } + ] + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "List tools", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + }, + "post": { + "description": "Create a new tool. Use this endpoint to define a custom tool with specific functionality and configuration for use by agents.

[Required authorization] Route required privileges: manage_agent_builder.", + "operationId": "post-agent-builder-tools", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "createEsqlToolRequest": { + "description": "Example request to create an ESQL query tool with a pre-defined query", + "value": { + "configuration": { + "params": { + "limit": { + "description": "Maximum number of results to return", + "type": "integer" + }, + "startTime": { + "description": "Start time for the analysis in ISO format", + "type": "date" + } + }, + "query": "FROM financial_trades | WHERE execution_timestamp >= ?startTime | STATS trade_count=COUNT(*), avg_price=AVG(execution_price) BY symbol | SORT trade_count DESC | LIMIT ?limit" + }, + "description": "Example ES|QL query tool for analyzing financial trades with time filtering", + "id": "example-esql-tool", + "tags": [ + "analytics", + "finance" + ], + "type": "esql" + } + }, + "createIndexSearchToolRequest": { + "description": "Example request to create an index_search tool with a pre-defined index pattern", + "value": { + "configuration": { + "pattern": "financial_*" + }, + "description": "Search tool specifically for financial data analysis and reporting", + "id": "example-index-search-tool", + "tags": [ + "search", + "finance" + ], + "type": "index_search" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "configuration": { + "additionalProperties": {}, + "description": "Tool-specific configuration parameters. See examples for details.", + "type": "object" + }, + "description": { + "default": "", + "description": "Description of what the tool does.", + "type": "string" + }, + "id": { + "description": "Unique identifier for the tool.", + "type": "string" + }, + "tags": { + "default": [], + "description": "Optional tags for categorizing and organizing tools.", + "items": { + "description": "Tag for categorizing the tool.", + "type": "string" + }, + "type": "array" + }, + "type": { + "description": "The type of tool to create (e.g., esql, index_search).", + "enum": [ + "esql", + "index_search", + "workflow", + "mcp" + ], + "type": "string" + } + }, + "required": [ + "id", + "type", + "configuration" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "createEsqlToolExample": { + "description": "Example response returning a definition of ESQL tool created", + "value": { + "configuration": { + "params": { + "limit": { + "description": "Maximum number of results to return", + "type": "integer" + }, + "startTime": { + "description": "Start time for the analysis in ISO format", + "type": "date" + } + }, + "query": "FROM financial_trades | WHERE execution_timestamp >= ?startTime | STATS trade_count=COUNT(*), avg_price=AVG(execution_price) BY symbol | SORT trade_count DESC | LIMIT ?limit" + }, + "description": "Example ES|QL query tool for analyzing financial trades with time filtering", + "id": "example-esql-tool", + "readonly": false, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Parameters needed to execute the query", + "properties": { + "limit": { + "description": "Maximum number of results to return", + "type": "integer" + }, + "startTime": { + "description": "Start time for the analysis in ISO format", + "format": "date-time", + "type": "string" + } + }, + "required": [ + "startTime", + "limit" + ], + "type": "object" + }, + "tags": [ + "analytics", + "finance" + ], + "type": "esql" + } + }, + "createIndexSearchToolExample": { + "description": "Example response returning a definition of search tool tool created", + "value": { + "configuration": { + "pattern": "financial_*" + }, + "description": "Search tool specifically for financial data analysis and reporting", + "id": "example-index-search-tool", + "readonly": false, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "nlQuery": { + "description": "A natural language query expressing the search request", + "type": "string" + } + }, + "required": [ + "nlQuery" + ], + "type": "object" + }, + "tags": [ + "search", + "finance" + ], + "type": "index_search" + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Create a tool", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + } + }, + "/api/agent_builder/tools/_execute": { + "post": { + "description": "Execute a tool with parameters. Use this endpoint to run a tool directly with specified inputs and optional external connector integration.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "post-agent-builder-tools-execute", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "executeBuiltinEsqlToolRequest": { + "description": "Example request executing platform.core.execute_esql tool", + "value": { + "tool_id": "platform.core.execute_esql", + "tool_params": { + "query": "FROM financial_trades | LIMIT 3" + } + } + }, + "executeBuiltinToolRequest": { + "description": "Example request executing platform.core.get_document_by_id tool", + "value": { + "tool_id": "platform.core.get_document_by_id", + "tool_params": { + "id": "TRD-20250805-0820a89f", + "index": "financial_trades" + } + } + }, + "executeCustomEsqlToolRequest": { + "description": "Example request executing custom example-esql-tool tool", + "value": { + "tool_id": "example-esql-tool", + "tool_params": { + "limit": 3, + "startTime": "2024-01-01T00:00:00Z" + } + } + }, + "executeIndexSearchToolRequest": { + "description": "Example request executing custom example-index-search-tool tool", + "value": { + "tool_id": "example-index-search-tool", + "tool_params": { + "nlQuery": "find trades with high execution prices above 100" + } + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "connector_id": { + "description": "Optional connector ID for tools that require external integrations.", + "type": "string" + }, + "tool_id": { + "description": "The ID of the tool to execute.", + "type": "string" + }, + "tool_params": { + "additionalProperties": {}, + "description": "Parameters to pass to the tool execution. See examples for details", + "type": "object" + } + }, + "required": [ + "tool_id", + "tool_params" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "executeBuiltinEsqlToolExample": { + "description": "Example response calling built-in platform.core.execute_esql tool", + "value": { + "results": [ + { + "data": { + "esql": "FROM financial_trades | LIMIT 3" + }, + "type": "query" + }, + { + "data": { + "columns": [ + { + "name": "account_id", + "type": "keyword" + }, + { + "name": "execution_price", + "type": "double" + }, + { + "name": "symbol", + "type": "keyword" + }, + { + "name": "trade_type", + "type": "keyword" + } + ], + "query": "FROM financial_trades | LIMIT 3", + "source": "esql", + "values": [ + [ + "ACC00179-1f91", + 43.77000045776367, + "CVX", + "sell" + ], + [ + "ACC00407-0bbb", + 660.4199829101562, + "V", + "buy" + ], + [ + "ACC00179-1f91", + 440.3599853515625, + "KO", + "buy" + ] + ] + }, + "tool_result_id": "xTpT", + "type": "tabular_data" + } + ] + } + }, + "executeBuiltinToolExample": { + "description": "Example response calling built-in platform.core.get_document_by_id tool", + "value": { + "results": [ + { + "data": { + "content": { + "account_id": "ACC00271-fb5c", + "execution_price": 488.54, + "execution_timestamp": "2025-08-05T08:04:11.649855", + "last_updated": "2025-09-15T13:23:36", + "order_status": "executed", + "order_type": "market", + "quantity": 131, + "status_reason": "fully_filled", + "symbol": "EWL", + "trade_cost": 63998.74, + "trade_id": "TRD-20250805-0820a89f", + "trade_type": "sell" + }, + "partial": false, + "reference": { + "id": "TRD-20250805-0820a89f", + "index": "financial_trades" + } + }, + "type": "resource" + } + ] + } + }, + "executeCustomEsqlToolExample": { + "description": "Example response calling custom example-esql-tool tool", + "value": { + "results": [ + { + "data": { + "columns": [ + { + "name": "trade_count", + "type": "long" + }, + { + "name": "avg_price", + "type": "double" + }, + { + "name": "symbol", + "type": "keyword" + } + ], + "query": "FROM financial_trades | WHERE execution_timestamp >= ?startTime | STATS trade_count=COUNT(*), avg_price=AVG(execution_price) BY symbol | SORT trade_count DESC | LIMIT ?limit", + "source": "esql", + "values": [ + [ + 2115, + 89.33911587329621, + "US_T_BOND_20YR" + ], + [ + 2112, + 104.20854155945055, + "INTL_CORP_ASIA_D" + ], + [ + 2105, + 89.93244177666526, + "INTL_CORP_EU_B" + ] + ] + }, + "tool_result_id": "Voy8", + "type": "tabular_data" + } + ] + } + }, + "executeIndexSearchToolExample": { + "description": "Example response calling custom example-index-search-tool tool", + "value": { + "results": [ + { + "data": { + "esql": "FROM financial_trades\n| WHERE execution_price > 100\n| LIMIT 100" + }, + "type": "query" + }, + { + "data": { + "columns": [ + { + "name": "account_id", + "type": "keyword" + }, + { + "name": "execution_price", + "type": "double" + }, + { + "name": "execution_timestamp", + "type": "date" + }, + { + "name": "symbol", + "type": "keyword" + }, + { + "name": "trade_type", + "type": "keyword" + } + ], + "query": "FROM financial_trades\n| WHERE execution_price > 100\n| LIMIT 100", + "source": "esql", + "values": [ + [ + "ACC00407-0bbb", + 660.4199829101562, + "2020-09-25T11:06:08.687Z", + "V", + "buy" + ], + [ + "ACC00179-1f91", + 440.3599853515625, + "2025-08-07T21:56:45.377Z", + "KO", + "buy" + ], + [ + "ACC00407-0bbb", + 132.8800048828125, + "2020-11-19T04:39:13.655Z", + "JAP_JGB_10YR", + "sell" + ] + ] + }, + "tool_result_id": "uE8y", + "type": "tabular_data" + } + ] + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Execute a Tool", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + } + }, + "/api/agent_builder/tools/{toolId}": { + "delete": { + "description": "Delete a tool by ID. This action cannot be undone.

[Required authorization] Route required privileges: manage_agent_builder.", + "operationId": "delete-agent-builder-tools-toolid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the tool to delete.", + "in": "path", + "name": "toolId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "deleteAgentResponseExample": { + "description": "Example response showing that the deletion operation was successful", + "value": { + "success": true + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Delete a tool", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + }, + "get": { + "description": "Get a specific tool by ID. Use this endpoint to retrieve the complete tool definition including its schema and configuration requirements.

[Required authorization] Route required privileges: read_agent_builder.", + "operationId": "get-agent-builder-tools-toolid", + "parameters": [ + { + "description": "The unique identifier of the tool to retrieve.", + "in": "path", + "name": "toolId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "getBuiltinToolExample": { + "description": "Example response returning built-in platform.core.search tool", + "value": { + "configuration": {}, + "description": "A powerful tool for searching and analyzing data within your Elasticsearch cluster.\nIt supports both full-text relevance searches and structured analytical queries.\n\nUse this tool for any query that involves finding documents, counting, aggregating, or summarizing data from a known index.\n\nExamples of queries:\n- \"find articles about serverless architecture\"\n- \"search for support tickets mentioning 'billing issue' or 'refund request'\"\n- \"what is our policy on parental leave?\"\n- \"list all products where the category is 'electronics'\"\n- \"show me the last 5 documents from that index\"\n- \"show me the sales over the last year break down by month\"\n\nNote:\n- The 'index' parameter can be used to specify which index to search against.\n If not provided, the tool will decide itself which is the best index to use.\n- It is perfectly fine not to specify the 'index' parameter. It should only be specified when you already\n know about the index and fields you want to search on, e.g. if the user explicitly specified it.", + "id": "platform.core.search", + "readonly": true, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "index": { + "description": "(optional) Index to search against. If not provided, will automatically select the best index to use based on the query.", + "type": "string" + }, + "query": { + "description": "A natural language query expressing the search request", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "tags": [], + "type": "builtin" + } + }, + "getEsqlToolExample": { + "description": "Example response returning custom example-esql-tool tool", + "value": { + "configuration": { + "params": { + "limit": { + "description": "Maximum number of results to return", + "type": "integer" + }, + "startTime": { + "description": "Start time for the analysis in ISO format", + "type": "date" + } + }, + "query": "FROM financial_trades | WHERE execution_timestamp >= ?startTime | STATS trade_count=COUNT(*), avg_price=AVG(execution_price) BY symbol | SORT trade_count DESC | LIMIT ?limit" + }, + "description": "Example ES|QL query tool for analyzing financial trades with time filtering", + "id": "example-esql-tool", + "readonly": false, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Parameters needed to execute the query", + "properties": { + "limit": { + "description": "Maximum number of results to return", + "type": "integer" + }, + "startTime": { + "description": "Start time for the analysis in ISO format", + "format": "date-time", + "type": "string" + } + }, + "required": [ + "startTime", + "limit" + ], + "type": "object" + }, + "tags": [ + "analytics", + "finance" + ], + "type": "esql" + } + }, + "getIndexSearchToolExample": { + "description": "Example response returning custom example-index-search-tool tool", + "value": { + "configuration": { + "pattern": "financial_*" + }, + "description": "Search tool specifically for financial data analysis and reporting", + "id": "example-index-search-tool", + "readonly": false, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "nlQuery": { + "description": "A natural language query expressing the search request", + "type": "string" + } + }, + "required": [ + "nlQuery" + ], + "type": "object" + }, + "tags": [ + "search", + "finance" + ], + "type": "index_search" + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Get a tool by id", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + }, + "put": { + "description": "Update an existing tool. Use this endpoint to modify any aspect of the tool's configuration or metadata.

[Required authorization] Route required privileges: manage_agent_builder.", + "operationId": "put-agent-builder-tools-toolid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the tool to update.", + "in": "path", + "name": "toolId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "updateEsqlToolRequest": { + "description": "Example request to update the custom ESQL tool", + "value": { + "configuration": { + "params": { + "limit": { + "description": "Maximum number of results to return", + "type": "integer" + }, + "startTime": { + "description": "Start time for the analysis in ISO format", + "type": "date" + }, + "symbolPattern": { + "description": "Pattern to filter symbols (e.g., 'US_*' for US instruments)", + "type": "keyword" + } + }, + "query": "FROM financial_trades | WHERE execution_timestamp >= ?startTime AND symbol LIKE ?symbolPattern | STATS trade_count=COUNT(*), avg_price=AVG(execution_price), total_volume=SUM(quantity) BY symbol | SORT trade_count DESC | LIMIT ?limit" + }, + "description": "Updated ES|QL query tool for comprehensive financial analysis with enhanced filtering", + "tags": [ + "analytics", + "finance", + "reporting" + ] + } + }, + "updateIndexSearchToolRequest": { + "description": "Example request to update the custom Search tool", + "value": { + "description": "Updated search tool for comprehensive financial data analysis, reporting, and compliance monitoring", + "tags": [ + "search", + "finance", + "compliance", + "reporting" + ] + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "configuration": { + "additionalProperties": {}, + "description": "Updated tool-specific configuration parameters. See examples for details.", + "type": "object" + }, + "description": { + "description": "Updated description of what the tool does.", + "type": "string" + }, + "tags": { + "description": "Updated tags for categorizing and organizing tools.", + "items": { + "description": "Updated tag for categorizing the tool.", + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "updateEsqlToolExample": { + "description": "Example response showing the updated ESQL tool", + "value": { + "configuration": { + "params": { + "limit": { + "description": "Maximum number of results to return", + "type": "integer" + }, + "startTime": { + "description": "Start time for the analysis in ISO format", + "type": "date" + }, + "symbolPattern": { + "description": "Pattern to filter symbols (e.g., 'US_*' for US instruments)", + "type": "keyword" + } + }, + "query": "FROM financial_trades | WHERE execution_timestamp >= ?startTime AND symbol LIKE ?symbolPattern | STATS trade_count=COUNT(*), avg_price=AVG(execution_price), total_volume=SUM(quantity) BY symbol | SORT trade_count DESC | LIMIT ?limit" + }, + "description": "Updated ES|QL query tool for comprehensive financial analysis with enhanced filtering", + "id": "example-esql-tool", + "readonly": false, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Parameters needed to execute the enhanced query", + "properties": { + "limit": { + "description": "Maximum number of results to return", + "type": "integer" + }, + "startTime": { + "description": "Start time for the analysis in ISO format", + "format": "date-time", + "type": "string" + }, + "symbolPattern": { + "description": "Pattern to filter symbols (e.g., 'US_*' for US instruments)", + "type": "string" + } + }, + "required": [ + "startTime", + "symbolPattern", + "limit" + ], + "type": "object" + }, + "tags": [ + "analytics", + "finance", + "reporting" + ], + "type": "esql" + } + }, + "updateIndexSearchToolExample": { + "description": "Example response showing the updated Search tool", + "value": { + "configuration": { + "pattern": "financial_*" + }, + "description": "Updated search tool for comprehensive financial data analysis, reporting, and compliance monitoring", + "id": "example-index-search-tool", + "readonly": false, + "schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "nlQuery": { + "description": "A natural language query expressing the search request", + "type": "string" + } + }, + "required": [ + "nlQuery" + ], + "type": "object" + }, + "tags": [ + "search", + "finance", + "compliance", + "reporting" + ], + "type": "index_search" + } + } + } + } + }, + "description": "Indicates a successful response" + } + }, + "summary": "Update a tool", + "tags": [ + "agent builder" + ], + "x-state": "Added in 9.2.0" + } + }, + "/api/alerting/rule/{id}": { + "delete": { + "operationId": "delete-alerting-rule-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the rule.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule with the given ID does not exist." + } + }, + "summary": "Delete a rule", + "tags": [ + "alerting" + ] + }, + "get": { + "operationId": "get-alerting-rule-id", + "parameters": [ + { + "description": "The identifier for the rule.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "actions": { + "items": { + "additionalProperties": false, + "properties": { + "alerts_filter": { + "additionalProperties": false, + "description": "Defines a period that limits whether the action runs.", + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "dsl": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL).", + "type": "string" + }, + "filters": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL) as defined in the `kbn-es-query` package.", + "items": { + "additionalProperties": false, + "properties": { + "$state": { + "additionalProperties": false, + "properties": { + "store": { + "description": "A filter can be either specific to an application context or applied globally.", + "enum": [ + "appState", + "globalState" + ], + "type": "string" + } + }, + "required": [ + "store" + ], + "type": "object" + }, + "meta": { + "additionalProperties": {}, + "type": "object" + }, + "query": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "meta" + ], + "type": "object" + }, + "type": "array" + }, + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql", + "filters" + ], + "type": "object" + }, + "timeframe": { + "additionalProperties": false, + "properties": { + "days": { + "description": "Defines the days of the week that the action can run, represented as an array of numbers. For example, `1` represents Monday. An empty array is equivalent to specifying all the days of the week.", + "items": { + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "type": "integer" + }, + "type": "array" + }, + "hours": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + }, + "start": { + "description": "The start of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + } + }, + "required": [ + "start", + "end" + ], + "type": "object" + }, + "timezone": { + "description": "The ISO time zone for the `hours` values. Values such as `UTC` and `UTC+1` also work but lack built-in daylight savings time support and are not recommended.", + "type": "string" + } + }, + "required": [ + "days", + "hours", + "timezone" + ], + "type": "object" + } + }, + "type": "object" + }, + "connector_type_id": { + "description": "The type of connector. This property appears in responses but cannot be set in requests.", + "type": "string" + }, + "frequency": { + "additionalProperties": false, + "properties": { + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "type": "string" + }, + "summary": { + "description": "Indicates whether the action is a summary.", + "type": "boolean" + }, + "throttle": { + "description": "The throttle interval, which defines how often an alert generates repeated actions. It is specified in seconds, minutes, hours, or days and is applicable only if 'notify_when' is set to 'onThrottleInterval'. NOTE: You cannot specify the throttle interval at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "summary", + "notify_when", + "throttle" + ], + "type": "object" + }, + "group": { + "description": "The group name, which affects when the action runs (for example, when the threshold is met or when the alert is recovered). Each rule type has a list of valid action group names. If you don't need to group actions, set to `default`.", + "type": "string" + }, + "id": { + "description": "The identifier for the connector saved object.", + "type": "string" + }, + "params": { + "additionalProperties": {}, + "description": "The parameters for the action, which are sent to the connector. The `params` are handled as Mustache templates and passed a default set of context.", + "type": "object" + }, + "use_alert_data_for_template": { + "description": "Indicates whether to use alert data as a template.", + "type": "boolean" + }, + "uuid": { + "description": "A universally unique identifier (UUID) for the action.", + "type": "string" + } + }, + "required": [ + "id", + "connector_type_id", + "params" + ], + "type": "object" + }, + "type": "array" + }, + "active_snoozes": { + "items": { + "description": "List of active snoozes for the rule.", + "type": "string" + }, + "type": "array" + }, + "alert_delay": { + "additionalProperties": false, + "description": "Indicates that an alert occurs only when the specified number of consecutive runs met the rule conditions.", + "properties": { + "active": { + "description": "The number of consecutive runs that must meet the rule conditions.", + "type": "number" + } + }, + "required": [ + "active" + ], + "type": "object" + }, + "api_key_created_by_user": { + "description": "Indicates whether the API key that is associated with the rule was created by the user.", + "nullable": true, + "type": "boolean" + }, + "api_key_owner": { + "description": "The owner of the API key that is associated with the rule and used to run background tasks.", + "nullable": true, + "type": "string" + }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" + } + }, + "type": "object" + }, + "consumer": { + "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", + "type": "string" + }, + "created_at": { + "description": "The date and time that the rule was created.", + "type": "string" + }, + "created_by": { + "description": "The identifier for the user that created the rule.", + "nullable": true, + "type": "string" + }, + "enabled": { + "description": "Indicates whether you want to run the rule on an interval basis after it is created.", + "type": "boolean" + }, + "execution_status": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "properties": { + "message": { + "description": "Error message.", + "type": "string" + }, + "reason": { + "description": "Reason for error.", + "enum": [ + "read", + "decrypt", + "execute", + "unknown", + "license", + "timeout", + "disabled", + "validate" + ], + "type": "string" + } + }, + "required": [ + "reason", + "message" + ], + "type": "object" + }, + "last_duration": { + "description": "Duration of last execution of the rule.", + "type": "number" + }, + "last_execution_date": { + "description": "The date and time when rule was executed last.", + "type": "string" + }, + "status": { + "description": "Status of rule execution.", + "enum": [ + "ok", + "active", + "error", + "warning", + "pending", + "unknown" + ], + "type": "string" + }, + "warning": { + "additionalProperties": false, + "properties": { + "message": { + "description": "Warning message.", + "type": "string" + }, + "reason": { + "description": "Reason for warning.", + "enum": [ + "maxExecutableActions", + "maxAlerts", + "maxQueuedActions", + "ruleExecution" + ], + "type": "string" + } + }, + "required": [ + "reason", + "message" + ], + "type": "object" + } + }, + "required": [ + "status", + "last_execution_date" + ], + "type": "object" + }, + "flapping": { + "additionalProperties": false, + "description": "When flapping detection is turned on, alerts that switch quickly between active and recovered states are identified as “flapping” and notifications are reduced.", + "nullable": true, + "properties": { + "enabled": { + "description": "Determines whether the rule can enter the flapping state. By default, rules can enter the flapping state.", + "type": "boolean" + }, + "look_back_window": { + "description": "The minimum number of runs in which the threshold must be met.", + "maximum": 20, + "minimum": 2, + "type": "number" + }, + "status_change_threshold": { + "description": "The minimum number of times an alert must switch states in the look back window.", + "maximum": 20, + "minimum": 2, + "type": "number" + } + }, + "required": [ + "look_back_window", + "status_change_threshold" + ], + "type": "object" + }, + "id": { + "description": "The identifier for the rule.", + "type": "string" + }, + "is_snoozed_until": { + "description": "The date when the rule will no longer be snoozed.", + "nullable": true, + "type": "string" + }, + "last_run": { + "additionalProperties": false, + "nullable": true, + "properties": { + "alerts_count": { + "additionalProperties": false, + "properties": { + "active": { + "description": "Number of active alerts during last run.", + "nullable": true, + "type": "number" + }, + "ignored": { + "description": "Number of ignored alerts during last run.", + "nullable": true, + "type": "number" + }, + "new": { + "description": "Number of new alerts during last run.", + "nullable": true, + "type": "number" + }, + "recovered": { + "description": "Number of recovered alerts during last run.", + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "outcome": { + "description": "Outcome of last run of the rule. Value could be succeeded, warning or failed.", + "enum": [ + "succeeded", + "warning", + "failed" + ], + "type": "string" + }, + "outcome_msg": { + "items": { + "description": "Outcome message generated during last rule run.", + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "outcome_order": { + "description": "Order of the outcome.", + "type": "number" + }, + "warning": { + "description": "Warning of last rule execution.", + "enum": [ + "read", + "decrypt", + "execute", + "unknown", + "license", + "timeout", + "disabled", + "validate", + "maxExecutableActions", + "maxAlerts", + "maxQueuedActions", + "ruleExecution" + ], + "nullable": true, + "type": "string" + } + }, + "required": [ + "outcome", + "alerts_count" + ], + "type": "object" + }, + "mapped_params": { + "additionalProperties": {}, + "type": "object" + }, + "monitoring": { + "additionalProperties": false, + "description": "Monitoring details of the rule.", + "properties": { + "run": { + "additionalProperties": false, + "description": "Rule run details.", + "properties": { + "calculated_metrics": { + "additionalProperties": false, + "description": "Calculation of different percentiles and success ratio.", + "properties": { + "p50": { + "type": "number" + }, + "p95": { + "type": "number" + }, + "p99": { + "type": "number" + }, + "success_ratio": { + "type": "number" + } + }, + "required": [ + "success_ratio" + ], + "type": "object" + }, + "history": { + "description": "History of the rule run.", + "items": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of the rule run.", + "type": "number" + }, + "outcome": { + "description": "Outcome of last run of the rule. Value could be succeeded, warning or failed.", + "enum": [ + "succeeded", + "warning", + "failed" + ], + "type": "string" + }, + "success": { + "description": "Indicates whether the rule run was successful.", + "type": "boolean" + }, + "timestamp": { + "description": "Time of rule run.", + "type": "number" + } + }, + "required": [ + "success", + "timestamp" + ], + "type": "object" + }, + "type": "array" + }, + "last_run": { + "additionalProperties": false, + "properties": { + "metrics": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of most recent rule run.", + "type": "number" + }, + "gap_duration_s": { + "description": "Duration in seconds of rule run gap.", + "nullable": true, + "type": "number" + }, + "gap_range": { + "additionalProperties": false, + "nullable": true, + "properties": { + "gte": { + "description": "End of the gap range.", + "type": "string" + }, + "lte": { + "description": "Start of the gap range.", + "type": "string" + } + }, + "required": [ + "lte", + "gte" + ], + "type": "object" + }, + "total_alerts_created": { + "description": "Total number of alerts created during last rule run.", + "nullable": true, + "type": "number" + }, + "total_alerts_detected": { + "description": "Total number of alerts detected during last rule run.", + "nullable": true, + "type": "number" + }, + "total_indexing_duration_ms": { + "description": "Total time spent indexing documents during last rule run in milliseconds.", + "nullable": true, + "type": "number" + }, + "total_search_duration_ms": { + "description": "Total time spent performing Elasticsearch searches as measured by Kibana; includes network latency and time spent serializing or deserializing the request and response.", + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "timestamp": { + "description": "Time of the most recent rule run.", + "type": "string" + } + }, + "required": [ + "timestamp", + "metrics" + ], + "type": "object" + } + }, + "required": [ + "history", + "calculated_metrics", + "last_run" + ], + "type": "object" + } + }, + "required": [ + "run" + ], + "type": "object" + }, + "mute_all": { + "description": "Indicates whether all alerts are muted.", + "type": "boolean" + }, + "muted_alert_ids": { + "items": { + "description": "List of identifiers of muted alerts. ", + "type": "string" + }, + "type": "array" + }, + "name": { + "description": " The name of the rule.", + "type": "string" + }, + "next_run": { + "description": "Date and time of the next run of the rule.", + "nullable": true, + "type": "string" + }, + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "nullable": true, + "type": "string" + }, + "params": { + "additionalProperties": {}, + "description": "The parameters for the rule.", + "type": "object" + }, + "revision": { + "description": "The rule revision number.", + "type": "number" + }, + "rule_type_id": { + "description": "The rule type identifier.", + "type": "string" + }, + "running": { + "description": "Indicates whether the rule is running.", + "nullable": true, + "type": "boolean" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "interval": { + "description": "The interval is specified in seconds, minutes, hours, or days.", + "type": "string" + } + }, + "required": [ + "interval" + ], + "type": "object" + }, + "scheduled_task_id": { + "description": "Identifier of the scheduled task.", + "type": "string" + }, + "snooze_schedule": { + "items": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of the rule snooze schedule.", + "type": "number" + }, + "id": { + "description": "Identifier of the rule snooze schedule.", + "type": "string" + }, + "rRule": { + "additionalProperties": false, + "properties": { + "byhour": { + "items": { + "description": "Indicates hours of the day to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byminute": { + "items": { + "description": "Indicates minutes of the hour to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bymonth": { + "items": { + "description": "Indicates months of the year that this rule should recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bymonthday": { + "items": { + "description": "Indicates the days of the month to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bysecond": { + "items": { + "description": "Indicates seconds of the day to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bysetpos": { + "items": { + "description": "A positive or negative integer affecting the nth day of the month. For example, -2 combined with `byweekday` of FR is 2nd to last Friday of the month. It is recommended to not set this manually and just use `byweekday`.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byweekday": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Indicates the days of the week to recur or else nth-day-of-month strings. For example, \"+2TU\" second Tuesday of month, \"-1FR\" last Friday of the month, which are internally converted to a `byweekday/bysetpos` combination." + }, + "nullable": true, + "type": "array" + }, + "byweekno": { + "items": { + "description": "Indicates number of the week hours to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byyearday": { + "items": { + "description": "Indicates the days of the year that this rule should recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "count": { + "description": "Number of times the rule should recur until it stops.", + "type": "number" + }, + "dtstart": { + "description": "Rule start date in Coordinated Universal Time (UTC).", + "type": "string" + }, + "freq": { + "description": "Indicates frequency of the rule. Options are YEARLY, MONTHLY, WEEKLY, DAILY.", + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6 + ], + "type": "integer" + }, + "interval": { + "description": "Indicates the interval of frequency. For example, 1 and YEARLY is every 1 year, 2 and WEEKLY is every 2 weeks.", + "type": "number" + }, + "tzid": { + "description": "Indicates timezone abbreviation.", + "type": "string" + }, + "until": { + "description": "Recur the rule until this date.", + "type": "string" + }, + "wkst": { + "description": "Indicates the start of week, defaults to Monday.", + "enum": [ + "MO", + "TU", + "WE", + "TH", + "FR", + "SA", + "SU" + ], + "type": "string" + } + }, + "required": [ + "dtstart", + "tzid" + ], + "type": "object" + }, + "skipRecurrences": { + "items": { + "description": "Skips recurrence of rule on this date.", + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "duration", + "rRule" + ], + "type": "object" + }, + "type": "array" + }, + "tags": { + "items": { + "description": "The tags for the rule.", + "type": "string" + }, + "type": "array" + }, + "throttle": { + "deprecated": true, + "description": "Deprecated in 8.13.0. Use the `throttle` property in the action `frequency` object instead. The throttle interval, which defines how often an alert generates repeated actions. NOTE: You cannot specify the throttle interval at both the rule and action level. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + }, + "updated_at": { + "description": "The date and time that the rule was updated most recently.", + "type": "string" + }, + "updated_by": { + "description": "The identifier for the user that updated this rule most recently.", + "nullable": true, + "type": "string" + }, + "view_in_app_relative_url": { + "description": "Relative URL to view rule in the app.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "enabled", + "name", + "tags", + "rule_type_id", + "consumer", + "schedule", + "actions", + "params", + "created_by", + "updated_by", + "created_at", + "updated_at", + "api_key_owner", + "mute_all", + "muted_alert_ids", + "execution_status", + "revision" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule with the given ID does not exist." + } + }, + "summary": "Get rule details", + "tags": [ + "alerting" + ] + }, + "post": { + "operationId": "post-alerting-rule-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the rule. If it is omitted, an ID is randomly generated.", + "in": "path", + "name": "id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "createEsQueryEsqlRuleRequest": { + "description": "Create an Elasticsearch query rule that uses Elasticsearch Query Language (ES|QL) to define its query and a server log connector to send notifications.\n", + "summary": "Elasticsearch query rule (ES|QL)", + "value": { + "actions": [ + { + "frequency": { + "notify_when": "onActiveAlert", + "summary": false + }, + "group": "query matched", + "id": "d0db1fe0-78d6-11ee-9177-f7d404c8c945", + "params": { + "level": "info", + "message": "Elasticsearch query rule '{{rule.name}}' is active:\n- Value: {{context.value}} - Conditions Met: {{context.conditions}} over {{rule.params.timeWindowSize}}{{rule.params.timeWindowUnit}} - Timestamp: {{context.date}} - Link: {{context.link}}" + } + } + ], + "consumer": "stackAlerts", + "name": "my Elasticsearch query ESQL rule", + "params": { + "esqlQuery": { + "esql": "FROM kibana_sample_data_logs | KEEP bytes, clientip, host, geo.dest | where geo.dest != \"GB\" | STATS sumbytes = sum(bytes) by clientip, host | WHERE sumbytes > 5000 | SORT sumbytes desc | LIMIT 10" + }, + "searchType": "esqlQuery", + "size": 0, + "threshold": [ + 0 + ], + "thresholdComparator": ">", + "timeField": "@timestamp", + "timeWindowSize": 1, + "timeWindowUnit": "d" + }, + "rule_type_id": ".es-query", + "schedule": { + "interval": "1d" + } + } + }, + "createEsQueryKqlRuleRequest": { + "description": "Create an Elasticsearch query rule that uses Kibana query language (KQL).", + "summary": "Elasticsearch query rule (KQL)", + "value": { + "consumer": "alerts", + "name": "my Elasticsearch query KQL rule", + "params": { + "aggType": "count", + "excludeHitsFromPreviousRun": true, + "groupBy": "all", + "searchConfiguration": { + "index": "90943e30-9a47-11e8-b64d-95841ca0b247", + "query": { + "language": "kuery", + "query": "\"\"geo.src : \"US\" \"\"" + } + }, + "searchType": "searchSource", + "size": 100, + "threshold": [ + 1000 + ], + "thresholdComparator": ">", + "timeWindowSize": 5, + "timeWindowUnit": "m" + }, + "rule_type_id": ".es-query", + "schedule": { + "interval": "1m" + } + } + }, + "createEsQueryRuleRequest": { + "description": "Create an Elasticsearch query rule that uses Elasticsearch query domain specific language (DSL) to define its query and a server log connector to send notifications.\n", + "summary": "Elasticsearch query rule (DSL)", + "value": { + "actions": [ + { + "frequency": { + "notify_when": "onThrottleInterval", + "summary": true, + "throttle": "1d" + }, + "group": "query matched", + "id": "fdbece50-406c-11ee-850e-c71febc4ca7f", + "params": { + "level": "info", + "message": "The system has detected {{alerts.new.count}} new, {{alerts.ongoing.count}} ongoing, and {{alerts.recovered.count}} recovered alerts." + } + }, + { + "frequency": { + "notify_when": "onActionGroupChange", + "summary": false + }, + "group": "recovered", + "id": "fdbece50-406c-11ee-850e-c71febc4ca7f", + "params": { + "level": "info", + "message": "Recovered" + } + } + ], + "consumer": "alerts", + "name": "my Elasticsearch query rule", + "params": { + "esQuery": "\"\"\"{\"query\":{\"match_all\" : {}}}\"\"\"", + "index": [ + "kibana_sample_data_logs" + ], + "size": 100, + "threshold": [ + 100 + ], + "thresholdComparator": ">", + "timeField": "@timestamp", + "timeWindowSize": 1, + "timeWindowUnit": "d" + }, + "rule_type_id": ".es-query", + "schedule": { + "interval": "1d" + } + } + }, + "createIndexThresholdRuleRequest": { + "description": "Create an index threshold rule that uses a server log connector to send notifications when the threshold is met.\n", + "summary": "Index threshold rule", + "value": { + "actions": [ + { + "frequency": { + "notify_when": "onActionGroupChange", + "summary": false + }, + "group": "threshold met", + "id": "48de3460-f401-11ed-9f8e-399c75a2deeb", + "params": { + "level": "info", + "message": "Rule '{{rule.name}}' is active for group '{{context.group}}':\n\n- Value: {{context.value}}\n- Conditions Met: {{context.conditions}} over {{rule.params.timeWindowSize}}{{rule.params.timeWindowUnit}}\n- Timestamp: {{context.date}}" + } + } + ], + "alert_delay": { + "active": 3 + }, + "consumer": "alerts", + "name": "my rule", + "params": { + "aggField": "sheet.version", + "aggType": "avg", + "groupBy": "top", + "index": [ + ".test-index" + ], + "termField": "name.keyword", + "termSize": 6, + "threshold": [ + 1000 + ], + "thresholdComparator": ">", + "timeField": "@timestamp", + "timeWindowSize": 5, + "timeWindowUnit": "m" + }, + "rule_type_id": ".index-threshold", + "schedule": { + "interval": "1m" + }, + "tags": [ + "cpu" + ] + } + }, + "createTrackingContainmentRuleRequest": { + "description": "Create a tracking containment rule that checks when an entity is contained or no longer contained within a boundary.\n", + "summary": "Tracking containment rule", + "value": { + "consumer": "alerts", + "name": "my tracking rule", + "params": { + "boundaryGeoField": "location", + "boundaryIndexId": "0cd90abf-abe7-44c7-909a-f621bbbcfefc", + "boundaryIndexTitle": "boundary*", + "boundaryNameField": "name", + "boundaryType": "entireIndex", + "dateField\"": "@timestamp", + "entity": "agent.keyword", + "geoField": "geo.coordinates", + "index": "kibana_sample_data_logs", + "indexId": "90943e30-9a47-11e8-b64d-95841ca0b247" + }, + "rule_type_id": ".geo-containment", + "schedule": { + "interval": "1h" + } + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "actions": { + "default": [], + "items": { + "additionalProperties": false, + "description": "An action that runs under defined conditions.", + "properties": { + "alerts_filter": { + "additionalProperties": false, + "description": "Conditions that affect whether the action runs. If you specify multiple conditions, all conditions must be met for the action to run. For example, if an alert occurs within the specified time frame and matches the query, the action runs.", + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "dsl": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL).", + "type": "string" + }, + "filters": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL) as defined in the `kbn-es-query` package.", + "items": { + "additionalProperties": false, + "properties": { + "$state": { + "additionalProperties": false, + "properties": { + "store": { + "description": "A filter can be either specific to an application context or applied globally.", + "enum": [ + "appState", + "globalState" + ], + "type": "string" + } + }, + "required": [ + "store" + ], + "type": "object" + }, + "meta": { + "additionalProperties": {}, + "type": "object" + }, + "query": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "meta" + ], + "type": "object" + }, + "type": "array" + }, + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql", + "filters" + ], + "type": "object" + }, + "timeframe": { + "additionalProperties": false, + "description": "Defines a period that limits whether the action runs.", + "properties": { + "days": { + "description": "Defines the days of the week that the action can run, represented as an array of numbers. For example, `1` represents Monday. An empty array is equivalent to specifying all the days of the week.", + "items": { + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "type": "integer" + }, + "type": "array" + }, + "hours": { + "additionalProperties": false, + "description": "Defines the range of time in a day that the action can run. If the `start` value is `00:00` and the `end` value is `24:00`, actions be generated all day.", + "properties": { + "end": { + "description": "The end of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + }, + "start": { + "description": "The start of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + } + }, + "required": [ + "start", + "end" + ], + "type": "object" + }, + "timezone": { + "description": "The ISO time zone for the `hours` values. Values such as `UTC` and `UTC+1` also work but lack built-in daylight savings time support and are not recommended.", + "type": "string" + } + }, + "required": [ + "days", + "hours", + "timezone" + ], + "type": "object" + } + }, + "type": "object" + }, + "frequency": { + "additionalProperties": false, + "properties": { + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "type": "string" + }, + "summary": { + "description": "Indicates whether the action is a summary.", + "type": "boolean" + }, + "throttle": { + "description": "The throttle interval, which defines how often an alert generates repeated actions. It is specified in seconds, minutes, hours, or days and is applicable only if `notify_when` is set to `onThrottleInterval`. NOTE: You cannot specify the throttle interval at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "summary", + "notify_when", + "throttle" + ], + "type": "object" + }, + "group": { + "description": "The group name, which affects when the action runs (for example, when the threshold is met or when the alert is recovered). Each rule type has a list of valid action group names. If you don't need to group actions, set to `default`.", + "type": "string" + }, + "id": { + "description": "The identifier for the connector saved object.", + "type": "string" + }, + "params": { + "additionalProperties": {}, + "default": {}, + "description": "The parameters for the action, which are sent to the connector. The `params` are handled as Mustache templates and passed a default set of context.", + "type": "object" + }, + "use_alert_data_for_template": { + "description": "Indicates whether to use alert data as a template.", + "type": "boolean" + }, + "uuid": { + "description": "A universally unique identifier (UUID) for the action.", + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + }, + "alert_delay": { + "additionalProperties": false, + "description": "Indicates that an alert occurs only when the specified number of consecutive runs met the rule conditions.", + "properties": { + "active": { + "description": "The number of consecutive runs that must meet the rule conditions.", + "type": "number" + } + }, + "required": [ + "active" + ], + "type": "object" + }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "maxLength": 10000, + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" + } + }, + "type": "object" + }, + "consumer": { + "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", + "type": "string" + }, + "enabled": { + "default": true, + "description": "Indicates whether you want to run the rule on an interval basis after it is created.", + "type": "boolean" + }, + "flapping": { + "additionalProperties": false, + "description": "When flapping detection is turned on, alerts that switch quickly between active and recovered states are identified as “flapping” and notifications are reduced.", + "nullable": true, + "properties": { + "enabled": { + "description": "Determines whether the rule can enter the flapping state. By default, rules can enter the flapping state.", + "type": "boolean" + }, + "look_back_window": { + "description": "The minimum number of runs in which the threshold must be met.", + "maximum": 20, + "minimum": 2, + "type": "number" + }, + "status_change_threshold": { + "description": "The minimum number of times an alert must switch states in the look back window.", + "maximum": 20, + "minimum": 2, + "type": "number" + } + }, + "required": [ + "look_back_window", + "status_change_threshold" + ], + "type": "object" + }, + "name": { + "description": "The name of the rule. While this name does not have to be unique, a distinctive name can help you identify a rule.", + "type": "string" + }, + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "nullable": true, + "type": "string" + }, + "params": { + "additionalProperties": {}, + "default": {}, + "description": "The parameters for the rule.", + "type": "object" + }, + "rule_type_id": { + "description": "The rule type identifier.", + "type": "string" + }, + "schedule": { + "additionalProperties": false, + "description": "The check interval, which specifies how frequently the rule conditions are checked.", + "properties": { + "interval": { + "description": "The interval is specified in seconds, minutes, hours, or days.", + "type": "string" + } + }, + "required": [ + "interval" + ], + "type": "object" + }, + "tags": { + "default": [], + "description": "The tags for the rule.", + "items": { + "type": "string" + }, + "type": "array" + }, + "throttle": { + "description": "Use the `throttle` property in the action `frequency` object instead. The throttle interval, which defines how often an alert generates repeated actions. NOTE: You cannot specify the throttle interval at both the rule and action level. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "name", + "rule_type_id", + "consumer", + "schedule" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "createEsQueryEsqlRuleResponse": { + "description": "The response for successfully creating an Elasticsearch query rule that uses Elasticsearch Query Language (ES|QL).", + "summary": "Elasticsearch query rule (ES|QL)", + "value": { + "actions": [ + { + "connector_type_id": ".server-log", + "frequency": { + "notify_when": "onActiveAlert", + "summary": false, + "throttle": null + }, + "group": "query matched", + "id": "d0db1fe0-78d6-11ee-9177-f7d404c8c945", + "params": { + "level": "info", + "message": "Elasticsearch query rule '{{rule.name}}' is active:\n- Value: {{context.value}} - Conditions Met: {{context.conditions}} over {{rule.params.timeWindowSize}}{{rule.params.timeWindowUnit}} - Timestamp: {{context.date}} - Link: {{context.link}}" + }, + "uuid": "bfe370a3-531b-4855-bbe6-ad739f578844" + } + ], + "api_key_created_by_user": false, + "api_key_owner": "elastic", + "consumer": "stackAlerts", + "created_at": "2023-11-01T19:00:10.453Z", + "created_by": "elastic", + "enabled": true, + "execution_status": { + "last_execution_date": "2023-11-01T19:00:10.453Z", + "status": "pending" + }, + "id": "e0d62360-78e8-11ee-9177-f7d404c8c945", + "mute_all": false, + "muted_alert_ids": [], + "name": "my Elasticsearch query ESQL rule", + "notify_when": null, + "params": { + "aggType": "count", + "esqlQuery": { + "esql": "FROM kibana_sample_data_logs | keep bytes, clientip, host, geo.dest | WHERE geo.dest != \"GB\" | stats sumbytes = sum(bytes) by clientip, host | WHERE sumbytes > 5000 | sort sumbytes desc | limit 10" + }, + "excludeHitsFromPreviousRun\"": "true,", + "groupBy": "all", + "searchType": "esqlQuery", + "size": 0, + "threshold": [ + 0 + ], + "thresholdComparator": ">", + "timeField": "@timestamp", + "timeWindowSize": 1, + "timeWindowUnit": "d" + }, + "revision": 0, + "rule_type_id": ".es-query", + "running": false, + "schedule": { + "interval": "1d" + }, + "scheduled_task_id": "e0d62360-78e8-11ee-9177-f7d404c8c945", + "tags": [], + "throttle": null, + "updated_at": "2023-11-01T19:00:10.453Z", + "updated_by": "elastic\"," + } + }, + "createEsQueryKqlRuleResponse": { + "description": "The response for successfully creating an Elasticsearch query rule that uses Kibana query language (KQL).", + "summary": "Elasticsearch query rule (KQL)", + "value": { + "actions": [], + "api_key_created_by_user": false, + "api_key_owner": "elastic", + "consumer": "alerts", + "created_at": "2023-07-14T20:24:50.729Z", + "created_by": "elastic", + "enabled": true, + "execution_status": { + "last_execution_date": "2023-07-14T20:24:50.729Z", + "status": "pending" + }, + "id": "7bd506d0-2284-11ee-8fad-6101956ced88", + "mute_all": false, + "muted_alert_ids": [], + "name": "my Elasticsearch query KQL rule\"", + "notify_when": null, + "params": { + "aggType": "count", + "excludeHitsFromPreviousRun": true, + "groupBy": "all", + "searchConfiguration": { + "index": "90943e30-9a47-11e8-b64d-95841ca0b247", + "query": { + "language": "kuery", + "query": "\"\"geo.src : \"US\" \"\"" + } + }, + "searchType": "searchSource", + "size": 100, + "threshold": [ + 1000 + ], + "thresholdComparator": ">", + "timeWindowSize": 5, + "timeWindowUnit": "m" + }, + "revision": 0, + "rule_type_id": ".es-query", + "running": false, + "schedule": { + "interval": "1m" + }, + "scheduled_task_id": "7bd506d0-2284-11ee-8fad-6101956ced88", + "tags": [], + "throttle": null, + "updated_at": "2023-07-14T20:24:50.729Z", + "updated_by": "elastic" + } + }, + "createEsQueryRuleResponse": { + "description": "The response for successfully creating an Elasticsearch query rule that uses Elasticsearch query domain specific language (DSL).", + "summary": "Elasticsearch query rule (DSL)", + "value": { + "actions": [ + { + "connector_type_id": ".server-log", + "frequency": { + "notify_when": "onThrottleInterval", + "summary": true, + "throttle": "1d" + }, + "group": "query matched", + "id": "fdbece50-406c-11ee-850e-c71febc4ca7f", + "params": { + "level": "info", + "message": "The system has detected {{alerts.new.count}} new, {{alerts.ongoing.count}} ongoing, and {{alerts.recovered.count}} recovered alerts." + }, + "uuid": "53f3c2a3-e5d0-4cfa-af3b-6f0881385e78" + }, + { + "connector_type_id": ".server-log", + "frequency": { + "notify_when": "onActionGroupChange", + "summary": false, + "throttle": null + }, + "group": "recovered", + "id": "fdbece50-406c-11ee-850e-c71febc4ca7f", + "params": { + "level": "info", + "message": "Recovered" + }, + "uuid": "2324e45b-c0df-45c7-9d70-4993e30be758" + } + ], + "api_key_created_by_user": false, + "api_key_owner": "elastic", + "consumer": "alerts", + "created_at": "2023-08-22T00:03:38.263Z", + "created_by": "elastic", + "enabled": true, + "execution_status": { + "last_execution_date": "2023-08-22T00:03:38.263Z", + "status": "pending" + }, + "id": "58148c70-407f-11ee-850e-c71febc4ca7f", + "mute_all": false, + "muted_alert_ids": [], + "name": "my Elasticsearch query rule", + "notify_when": null, + "params": { + "aggType": "count", + "esQuery": "\"\"\"{\"query\":{\"match_all\" : {}}}\"\"\"", + "excludeHitsFromPreviousRun": true, + "groupBy": "all", + "index": [ + "kibana_sample_data_logs" + ], + "searchType": "esQuery", + "size": 100, + "threshold": [ + 100 + ], + "thresholdComparator": ">", + "timeField": "@timestamp", + "timeWindowSize": 1, + "timeWindowUnit": "d" + }, + "revision": 0, + "rule_type_id": ".es-query", + "running": false, + "schedule": { + "interval": "1d" + }, + "scheduled_task_id": "58148c70-407f-11ee-850e-c71febc4ca7f", + "tags": [], + "throttle": null, + "updated_at": "2023-08-22T00:03:38.263Z", + "updated_by": "elastic" + } + }, + "createIndexThresholdRuleResponse": { + "description": "The response for successfully creating an index threshold rule.", + "summary": "Index threshold rule", + "value": { + "actions": [ + { + "connector_type_id": ".server-log", + "frequency": { + "notify_when": "onActionGroupChange", + "summary": false, + "throttle": null + }, + "group": "threshold met", + "id": "dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2", + "params": { + "level": "info", + "message": "Rule {{rule.name}} is active for group {{context.group} :\n\n- Value: {{context.value}}\n- Conditions Met: {{context.conditions}} over {{rule.params.timeWindowSize}}{{rule.params.timeWindowUnit}}\n- Timestamp: {{context.date}}" + }, + "uuid": "07aef2a0-9eed-4ef9-94ec-39ba58eb609d" + } + ], + "alert_delay": { + "active": 3 + }, + "api_key_created_by_user": false, + "api_key_owner": "elastic", + "consumer": "alerts", + "created_at": "2022-06-08T17:20:31.632Z", + "created_by": "elastic", + "enabled": true, + "execution_status": { + "last_execution_date": "2022-06-08T17:20:31.632Z", + "status": "pending" + }, + "id": "41893910-6bca-11eb-9e0d-85d233e3ee35", + "mute_all": false, + "muted_alert_ids": [], + "name": "my rule", + "notify_when": null, + "params": { + "aggField": "sheet.version", + "aggType": "avg", + "groupBy": "top", + "index": [ + ".test-index" + ], + "termField": "name.keyword", + "termSize": 6, + "threshold": [ + 1000 + ], + "thresholdComparator": ">", + "timeField": "@timestamp", + "timeWindowSize": 5, + "timeWindowUnit": "m" + }, + "revision": 0, + "rule_type_id": ".index-threshold", + "running": false, + "schedule": { + "interval": "1m" + }, + "scheduled_task_id": "425b0800-6bca-11eb-9e0d-85d233e3ee35", + "tags": [ + "cpu" + ], + "throttle": null, + "updated_at": "2022-06-08T17:20:31.632Z", + "updated_by": "elastic" + } + }, + "createTrackingContainmentRuleResponse": { + "description": "The response for successfully creating a tracking containment rule.", + "summary": "Tracking containment rule", + "value": { + "actions": [], + "api_key_created_by_user": false, + "api_key_owner": "elastic", + "consumer": "alerts", + "created_at": "2024-02-14T19:52:55.920Z", + "created_by": "elastic", + "enabled": true, + "execution_status": { + "last_duration": 74, + "last_execution_date": "2024-02-15T03:25:38.125Z", + "status": "ok" + }, + "id": "b6883f9d-5f70-4758-a66e-369d7c26012f", + "last_run": { + "alerts_count": { + "active": 0, + "ignored": 0, + "new": 0, + "recovered": 0 + }, + "outcome": "succeeded", + "outcome_msg": null, + "outcome_order": 0, + "warning": null + }, + "mute_all": false, + "muted_alert_ids": [], + "name": "my tracking rule", + "next_run": "2024-02-15T03:26:38.033Z", + "notify_when": null, + "params": { + "boundaryGeoField": "location", + "boundaryIndexId": "0cd90abf-abe7-44c7-909a-f621bbbcfefc", + "boundaryIndexTitle": "boundary*", + "boundaryNameField": "name", + "boundaryType": "entireIndex", + "dateField": "@timestamp", + "entity": "agent.keyword", + "geoField": "geo.coordinates", + "index": "kibana_sample_data_logs", + "indexId": "90943e30-9a47-11e8-b64d-95841ca0b247" + }, + "revision": 1, + "rule_type_id": ".geo-containment", + "running": false, + "schedule": { + "interval": "1h" + }, + "scheduled_task_id": "b6883f9d-5f70-4758-a66e-369d7c26012f", + "tags": [], + "throttle": null, + "updated_at": "2024-02-15T03:24:32.574Z", + "updated_by": "elastic" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "actions": { + "items": { + "additionalProperties": false, + "properties": { + "alerts_filter": { + "additionalProperties": false, + "description": "Defines a period that limits whether the action runs.", + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "dsl": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL).", + "type": "string" + }, + "filters": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL) as defined in the `kbn-es-query` package.", + "items": { + "additionalProperties": false, + "properties": { + "$state": { + "additionalProperties": false, + "properties": { + "store": { + "description": "A filter can be either specific to an application context or applied globally.", + "enum": [ + "appState", + "globalState" + ], + "type": "string" + } + }, + "required": [ + "store" + ], + "type": "object" + }, + "meta": { + "additionalProperties": {}, + "type": "object" + }, + "query": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "meta" + ], + "type": "object" + }, + "type": "array" + }, + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql", + "filters" + ], + "type": "object" + }, + "timeframe": { + "additionalProperties": false, + "properties": { + "days": { + "description": "Defines the days of the week that the action can run, represented as an array of numbers. For example, `1` represents Monday. An empty array is equivalent to specifying all the days of the week.", + "items": { + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "type": "integer" + }, + "type": "array" + }, + "hours": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + }, + "start": { + "description": "The start of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + } + }, + "required": [ + "start", + "end" + ], + "type": "object" + }, + "timezone": { + "description": "The ISO time zone for the `hours` values. Values such as `UTC` and `UTC+1` also work but lack built-in daylight savings time support and are not recommended.", + "type": "string" + } + }, + "required": [ + "days", + "hours", + "timezone" + ], + "type": "object" + } + }, + "type": "object" + }, + "connector_type_id": { + "description": "The type of connector. This property appears in responses but cannot be set in requests.", + "type": "string" + }, + "frequency": { + "additionalProperties": false, + "properties": { + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "type": "string" + }, + "summary": { + "description": "Indicates whether the action is a summary.", + "type": "boolean" + }, + "throttle": { + "description": "The throttle interval, which defines how often an alert generates repeated actions. It is specified in seconds, minutes, hours, or days and is applicable only if 'notify_when' is set to 'onThrottleInterval'. NOTE: You cannot specify the throttle interval at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "summary", + "notify_when", + "throttle" + ], + "type": "object" + }, + "group": { + "description": "The group name, which affects when the action runs (for example, when the threshold is met or when the alert is recovered). Each rule type has a list of valid action group names. If you don't need to group actions, set to `default`.", + "type": "string" + }, + "id": { + "description": "The identifier for the connector saved object.", + "type": "string" + }, + "params": { + "additionalProperties": {}, + "description": "The parameters for the action, which are sent to the connector. The `params` are handled as Mustache templates and passed a default set of context.", + "type": "object" + }, + "use_alert_data_for_template": { + "description": "Indicates whether to use alert data as a template.", + "type": "boolean" + }, + "uuid": { + "description": "A universally unique identifier (UUID) for the action.", + "type": "string" + } + }, + "required": [ + "id", + "connector_type_id", + "params" + ], + "type": "object" + }, + "type": "array" + }, + "active_snoozes": { + "items": { + "description": "List of active snoozes for the rule.", + "type": "string" + }, + "type": "array" + }, + "alert_delay": { + "additionalProperties": false, + "description": "Indicates that an alert occurs only when the specified number of consecutive runs met the rule conditions.", + "properties": { + "active": { + "description": "The number of consecutive runs that must meet the rule conditions.", + "type": "number" + } + }, + "required": [ + "active" + ], + "type": "object" + }, + "api_key_created_by_user": { + "description": "Indicates whether the API key that is associated with the rule was created by the user.", + "nullable": true, + "type": "boolean" + }, + "api_key_owner": { + "description": "The owner of the API key that is associated with the rule and used to run background tasks.", + "nullable": true, + "type": "string" + }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" + } + }, + "type": "object" + }, + "consumer": { + "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", + "type": "string" + }, + "created_at": { + "description": "The date and time that the rule was created.", + "type": "string" + }, + "created_by": { + "description": "The identifier for the user that created the rule.", + "nullable": true, + "type": "string" + }, + "enabled": { + "description": "Indicates whether you want to run the rule on an interval basis after it is created.", + "type": "boolean" + }, + "execution_status": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "properties": { + "message": { + "description": "Error message.", + "type": "string" + }, + "reason": { + "description": "Reason for error.", + "enum": [ + "read", + "decrypt", + "execute", + "unknown", + "license", + "timeout", + "disabled", + "validate" + ], + "type": "string" + } + }, + "required": [ + "reason", + "message" + ], + "type": "object" + }, + "last_duration": { + "description": "Duration of last execution of the rule.", + "type": "number" + }, + "last_execution_date": { + "description": "The date and time when rule was executed last.", + "type": "string" + }, + "status": { + "description": "Status of rule execution.", + "enum": [ + "ok", + "active", + "error", + "warning", + "pending", + "unknown" + ], + "type": "string" + }, + "warning": { + "additionalProperties": false, + "properties": { + "message": { + "description": "Warning message.", + "type": "string" + }, + "reason": { + "description": "Reason for warning.", + "enum": [ + "maxExecutableActions", + "maxAlerts", + "maxQueuedActions", + "ruleExecution" + ], + "type": "string" + } + }, + "required": [ + "reason", + "message" + ], + "type": "object" + } + }, + "required": [ + "status", + "last_execution_date" + ], + "type": "object" + }, + "flapping": { + "additionalProperties": false, + "description": "When flapping detection is turned on, alerts that switch quickly between active and recovered states are identified as “flapping” and notifications are reduced.", + "nullable": true, + "properties": { + "enabled": { + "description": "Determines whether the rule can enter the flapping state. By default, rules can enter the flapping state.", + "type": "boolean" + }, + "look_back_window": { + "description": "The minimum number of runs in which the threshold must be met.", + "maximum": 20, + "minimum": 2, + "type": "number" + }, + "status_change_threshold": { + "description": "The minimum number of times an alert must switch states in the look back window.", + "maximum": 20, + "minimum": 2, + "type": "number" + } + }, + "required": [ + "look_back_window", + "status_change_threshold" + ], + "type": "object" + }, + "id": { + "description": "The identifier for the rule.", + "type": "string" + }, + "is_snoozed_until": { + "description": "The date when the rule will no longer be snoozed.", + "nullable": true, + "type": "string" + }, + "last_run": { + "additionalProperties": false, + "nullable": true, + "properties": { + "alerts_count": { + "additionalProperties": false, + "properties": { + "active": { + "description": "Number of active alerts during last run.", + "nullable": true, + "type": "number" + }, + "ignored": { + "description": "Number of ignored alerts during last run.", + "nullable": true, + "type": "number" + }, + "new": { + "description": "Number of new alerts during last run.", + "nullable": true, + "type": "number" + }, + "recovered": { + "description": "Number of recovered alerts during last run.", + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "outcome": { + "description": "Outcome of last run of the rule. Value could be succeeded, warning or failed.", + "enum": [ + "succeeded", + "warning", + "failed" + ], + "type": "string" + }, + "outcome_msg": { + "items": { + "description": "Outcome message generated during last rule run.", + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "outcome_order": { + "description": "Order of the outcome.", + "type": "number" + }, + "warning": { + "description": "Warning of last rule execution.", + "enum": [ + "read", + "decrypt", + "execute", + "unknown", + "license", + "timeout", + "disabled", + "validate", + "maxExecutableActions", + "maxAlerts", + "maxQueuedActions", + "ruleExecution" + ], + "nullable": true, + "type": "string" + } + }, + "required": [ + "outcome", + "alerts_count" + ], + "type": "object" + }, + "mapped_params": { + "additionalProperties": {}, + "type": "object" + }, + "monitoring": { + "additionalProperties": false, + "description": "Monitoring details of the rule.", + "properties": { + "run": { + "additionalProperties": false, + "description": "Rule run details.", + "properties": { + "calculated_metrics": { + "additionalProperties": false, + "description": "Calculation of different percentiles and success ratio.", + "properties": { + "p50": { + "type": "number" + }, + "p95": { + "type": "number" + }, + "p99": { + "type": "number" + }, + "success_ratio": { + "type": "number" + } + }, + "required": [ + "success_ratio" + ], + "type": "object" + }, + "history": { + "description": "History of the rule run.", + "items": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of the rule run.", + "type": "number" + }, + "outcome": { + "description": "Outcome of last run of the rule. Value could be succeeded, warning or failed.", + "enum": [ + "succeeded", + "warning", + "failed" + ], + "type": "string" + }, + "success": { + "description": "Indicates whether the rule run was successful.", + "type": "boolean" + }, + "timestamp": { + "description": "Time of rule run.", + "type": "number" + } + }, + "required": [ + "success", + "timestamp" + ], + "type": "object" + }, + "type": "array" + }, + "last_run": { + "additionalProperties": false, + "properties": { + "metrics": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of most recent rule run.", + "type": "number" + }, + "gap_duration_s": { + "description": "Duration in seconds of rule run gap.", + "nullable": true, + "type": "number" + }, + "gap_range": { + "additionalProperties": false, + "nullable": true, + "properties": { + "gte": { + "description": "End of the gap range.", + "type": "string" + }, + "lte": { + "description": "Start of the gap range.", + "type": "string" + } + }, + "required": [ + "lte", + "gte" + ], + "type": "object" + }, + "total_alerts_created": { + "description": "Total number of alerts created during last rule run.", + "nullable": true, + "type": "number" + }, + "total_alerts_detected": { + "description": "Total number of alerts detected during last rule run.", + "nullable": true, + "type": "number" + }, + "total_indexing_duration_ms": { + "description": "Total time spent indexing documents during last rule run in milliseconds.", + "nullable": true, + "type": "number" + }, + "total_search_duration_ms": { + "description": "Total time spent performing Elasticsearch searches as measured by Kibana; includes network latency and time spent serializing or deserializing the request and response.", + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "timestamp": { + "description": "Time of the most recent rule run.", + "type": "string" + } + }, + "required": [ + "timestamp", + "metrics" + ], + "type": "object" + } + }, + "required": [ + "history", + "calculated_metrics", + "last_run" + ], + "type": "object" + } + }, + "required": [ + "run" + ], + "type": "object" + }, + "mute_all": { + "description": "Indicates whether all alerts are muted.", + "type": "boolean" + }, + "muted_alert_ids": { + "items": { + "description": "List of identifiers of muted alerts. ", + "type": "string" + }, + "type": "array" + }, + "name": { + "description": " The name of the rule.", + "type": "string" + }, + "next_run": { + "description": "Date and time of the next run of the rule.", + "nullable": true, + "type": "string" + }, + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "nullable": true, + "type": "string" + }, + "params": { + "additionalProperties": {}, + "description": "The parameters for the rule.", + "type": "object" + }, + "revision": { + "description": "The rule revision number.", + "type": "number" + }, + "rule_type_id": { + "description": "The rule type identifier.", + "type": "string" + }, + "running": { + "description": "Indicates whether the rule is running.", + "nullable": true, + "type": "boolean" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "interval": { + "description": "The interval is specified in seconds, minutes, hours, or days.", + "type": "string" + } + }, + "required": [ + "interval" + ], + "type": "object" + }, + "scheduled_task_id": { + "description": "Identifier of the scheduled task.", + "type": "string" + }, + "snooze_schedule": { + "items": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of the rule snooze schedule.", + "type": "number" + }, + "id": { + "description": "Identifier of the rule snooze schedule.", + "type": "string" + }, + "rRule": { + "additionalProperties": false, + "properties": { + "byhour": { + "items": { + "description": "Indicates hours of the day to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byminute": { + "items": { + "description": "Indicates minutes of the hour to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bymonth": { + "items": { + "description": "Indicates months of the year that this rule should recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bymonthday": { + "items": { + "description": "Indicates the days of the month to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bysecond": { + "items": { + "description": "Indicates seconds of the day to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bysetpos": { + "items": { + "description": "A positive or negative integer affecting the nth day of the month. For example, -2 combined with `byweekday` of FR is 2nd to last Friday of the month. It is recommended to not set this manually and just use `byweekday`.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byweekday": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Indicates the days of the week to recur or else nth-day-of-month strings. For example, \"+2TU\" second Tuesday of month, \"-1FR\" last Friday of the month, which are internally converted to a `byweekday/bysetpos` combination." + }, + "nullable": true, + "type": "array" + }, + "byweekno": { + "items": { + "description": "Indicates number of the week hours to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byyearday": { + "items": { + "description": "Indicates the days of the year that this rule should recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "count": { + "description": "Number of times the rule should recur until it stops.", + "type": "number" + }, + "dtstart": { + "description": "Rule start date in Coordinated Universal Time (UTC).", + "type": "string" + }, + "freq": { + "description": "Indicates frequency of the rule. Options are YEARLY, MONTHLY, WEEKLY, DAILY.", + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6 + ], + "type": "integer" + }, + "interval": { + "description": "Indicates the interval of frequency. For example, 1 and YEARLY is every 1 year, 2 and WEEKLY is every 2 weeks.", + "type": "number" + }, + "tzid": { + "description": "Indicates timezone abbreviation.", + "type": "string" + }, + "until": { + "description": "Recur the rule until this date.", + "type": "string" + }, + "wkst": { + "description": "Indicates the start of week, defaults to Monday.", + "enum": [ + "MO", + "TU", + "WE", + "TH", + "FR", + "SA", + "SU" + ], + "type": "string" + } + }, + "required": [ + "dtstart", + "tzid" + ], + "type": "object" + }, + "skipRecurrences": { + "items": { + "description": "Skips recurrence of rule on this date.", + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "duration", + "rRule" + ], + "type": "object" + }, + "type": "array" + }, + "tags": { + "items": { + "description": "The tags for the rule.", + "type": "string" + }, + "type": "array" + }, + "throttle": { + "deprecated": true, + "description": "Deprecated in 8.13.0. Use the `throttle` property in the action `frequency` object instead. The throttle interval, which defines how often an alert generates repeated actions. NOTE: You cannot specify the throttle interval at both the rule and action level. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + }, + "updated_at": { + "description": "The date and time that the rule was updated most recently.", + "type": "string" + }, + "updated_by": { + "description": "The identifier for the user that updated this rule most recently.", + "nullable": true, + "type": "string" + }, + "view_in_app_relative_url": { + "description": "Relative URL to view rule in the app.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "enabled", + "name", + "tags", + "rule_type_id", + "consumer", + "schedule", + "actions", + "params", + "created_by", + "updated_by", + "created_at", + "updated_at", + "api_key_owner", + "mute_all", + "muted_alert_ids", + "execution_status", + "revision" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "409": { + "description": "Indicates that the rule id is already in use." + } + }, + "summary": "Create a rule", + "tags": [ + "alerting" + ] + }, + "put": { + "operationId": "put-alerting-rule-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the rule.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "updateRuleRequest": { + "description": "Update an index threshold rule that uses a server log connector to send notifications when the threshold is met.", + "summary": "Index threshold rule", + "value": { + "actions": [ + { + "frequency": { + "notify_when": "onActionGroupChange", + "summary": false + }, + "group": "threshold met", + "id": "96b668d0-a1b6-11ed-afdf-d39a49596974", + "params": { + "level": "info", + "message": "Rule {{rule.name}} is active for group {{context.group}}:\n\n- Value: {{context.value}}\n- Conditions Met: {{context.conditions}} over {{rule.params.timeWindowSize}}{{rule.params.timeWindowUnit}}\n- Timestamp: {{context.date}}" + } + } + ], + "name": "new name", + "params": { + "aggField": "sheet.version", + "aggType": "avg", + "groupBy": "top", + "index": [ + ".updated-index" + ], + "termField": "name.keyword", + "termSize": 6, + "threshold": [ + 1000 + ], + "thresholdComparator": ">", + "timeField": "@timestamp", + "timeWindowSize": 5, + "timeWindowUnit": "m" + }, + "schedule": { + "interval": "1m" + }, + "tags": [] + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "actions": { + "default": [], + "items": { + "additionalProperties": false, + "description": "An action that runs under defined conditions.", + "properties": { + "alerts_filter": { + "additionalProperties": false, + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "dsl": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL).", + "type": "string" + }, + "filters": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL) as defined in the `kbn-es-query` package.", + "items": { + "additionalProperties": false, + "properties": { + "$state": { + "additionalProperties": false, + "properties": { + "store": { + "description": "A filter can be either specific to an application context or applied globally.", + "enum": [ + "appState", + "globalState" + ], + "type": "string" + } + }, + "required": [ + "store" + ], + "type": "object" + }, + "meta": { + "additionalProperties": {}, + "type": "object" + }, + "query": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "meta" + ], + "type": "object" + }, + "type": "array" + }, + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql", + "filters" + ], + "type": "object" + }, + "timeframe": { + "additionalProperties": false, + "description": "Defines a period that limits whether the action runs.", + "properties": { + "days": { + "description": "Defines the days of the week that the action can run, represented as an array of numbers. For example, `1` represents Monday. An empty array is equivalent to specifying all the days of the week.", + "items": { + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "type": "integer" + }, + "type": "array" + }, + "hours": { + "additionalProperties": false, + "description": "Defines the range of time in a day that the action can run. If the `start` value is `00:00` and the `end` value is `24:00`, actions be generated all day.", + "properties": { + "end": { + "description": "The end of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + }, + "start": { + "description": "The start of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + } + }, + "required": [ + "start", + "end" + ], + "type": "object" + }, + "timezone": { + "description": "The ISO time zone for the `hours` values. Values such as `UTC` and `UTC+1` also work but lack built-in daylight savings time support and are not recommended.", + "type": "string" + } + }, + "required": [ + "days", + "hours", + "timezone" + ], + "type": "object" + } + }, + "type": "object" + }, + "frequency": { + "additionalProperties": false, + "properties": { + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "type": "string" + }, + "summary": { + "description": "Indicates whether the action is a summary.", + "type": "boolean" + }, + "throttle": { + "description": "The throttle interval, which defines how often an alert generates repeated actions. It is specified in seconds, minutes, hours, or days and is applicable only if `notify_when` is set to `onThrottleInterval`. NOTE: You cannot specify the throttle interval at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "summary", + "notify_when", + "throttle" + ], + "type": "object" + }, + "group": { + "description": "The group name, which affects when the action runs (for example, when the threshold is met or when the alert is recovered). Each rule type has a list of valid action group names. If you don't need to group actions, set to `default`.", + "type": "string" + }, + "id": { + "description": "The identifier for the connector saved object.", + "type": "string" + }, + "params": { + "additionalProperties": {}, + "default": {}, + "description": "The parameters for the action, which are sent to the connector. The `params` are handled as Mustache templates and passed a default set of context.", + "type": "object" + }, + "use_alert_data_for_template": { + "description": "Indicates whether to use alert data as a template.", + "type": "boolean" + }, + "uuid": { + "description": "A universally unique identifier (UUID) for the action.", + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + }, + "alert_delay": { + "additionalProperties": false, + "description": "Indicates that an alert occurs only when the specified number of consecutive runs met the rule conditions.", + "properties": { + "active": { + "description": "The number of consecutive runs that must meet the rule conditions.", + "type": "number" + } + }, + "required": [ + "active" + ], + "type": "object" + }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "maxLength": 10000, + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" + } + }, + "type": "object" + }, + "flapping": { + "additionalProperties": false, + "description": "When flapping detection is turned on, alerts that switch quickly between active and recovered states are identified as “flapping” and notifications are reduced.", + "nullable": true, + "properties": { + "enabled": { + "description": "Determines whether the rule can enter the flapping state. By default, rules can enter the flapping state.", + "type": "boolean" + }, + "look_back_window": { + "description": "The minimum number of runs in which the threshold must be met.", + "maximum": 20, + "minimum": 2, + "type": "number" + }, + "status_change_threshold": { + "description": "The minimum number of times an alert must switch states in the look back window.", + "maximum": 20, + "minimum": 2, + "type": "number" + } + }, + "required": [ + "look_back_window", + "status_change_threshold" + ], + "type": "object" + }, + "name": { + "description": "The name of the rule. While this name does not have to be unique, a distinctive name can help you identify a rule.", + "type": "string" + }, + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "nullable": true, + "type": "string" + }, + "params": { + "additionalProperties": {}, + "default": {}, + "description": "The parameters for the rule.", + "type": "object" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "interval": { + "description": "The interval is specified in seconds, minutes, hours, or days.", + "type": "string" + } + }, + "required": [ + "interval" + ], + "type": "object" + }, + "tags": { + "default": [], + "items": { + "description": "The tags for the rule.", + "type": "string" + }, + "type": "array" + }, + "throttle": { + "description": "Use the `throttle` property in the action `frequency` object instead. The throttle interval, which defines how often an alert generates repeated actions. NOTE: You cannot specify the throttle interval at both the rule and action level. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "name", + "schedule" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "updateRuleResponse": { + "description": "The response for successfully updating an index threshold rule.", + "summary": "Index threshold rule", + "value": { + "actions": [ + { + "connector_type_id": ".server-log", + "frequency": { + "notify_when": "onActionGroupChange", + "summary": false, + "throttle": null + }, + "group": "threshold met", + "id": "96b668d0-a1b6-11ed-afdf-d39a49596974", + "params": { + "level": "info", + "message": "Rule {{rule.name}} is active for group {{context.group}}:\n\n- Value: {{context.value}}\n- Conditions Met: {{context.conditions}} over {{rule.params.timeWindowSize}}{{rule.params.timeWindowUnit}}\n- Timestamp: {{context.date}" + }, + "uuid": "07aef2a0-9eed-4ef9-94ec-39ba58eb609d" + } + ], + "api_key_created_by_user": false, + "api_key_owner": "elastic", + "consumer": "alerts", + "created_at": "2024-03-26T23:13:20.985Z", + "created_by": "elastic", + "enabled": true, + "execution_status": { + "last_duration": 52, + "last_execution_date": "2024-03-26T23:22:51.390Z", + "status": "ok" + }, + "id": "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74", + "last_run": { + "alerts_count": { + "active": 0, + "ignored": 0, + "new": 0, + "recovered": 0 + }, + "outcome": "succeeded", + "outcome_msg": null, + "warning": null + }, + "mute_all": false, + "muted_alert_ids": [], + "name": "new name", + "next_run": "2024-03-26T23:23:51.316Z", + "params": { + "aggField": "sheet.version", + "aggType": "avg", + "groupBy": "top", + "index": [ + ".updated-index" + ], + "termField": "name.keyword", + "termSize": 6, + "threshold": [ + 1000 + ], + "thresholdComparator": ">", + "timeField": "@timestamp", + "timeWindowSize": 5, + "timeWindowUnit": "m" + }, + "revision": 1, + "rule_type_id": ".index-threshold", + "running": false, + "schedule": { + "interval": "1m" + }, + "scheduled_task_id": "4c5eda00-e74f-11ec-b72f-5b18752ff9ea", + "tags": [], + "throttle": null, + "updated_at": "2024-03-26T23:22:59.949Z", + "updated_by": "elastic" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "actions": { + "items": { + "additionalProperties": false, + "properties": { + "alerts_filter": { + "additionalProperties": false, + "description": "Defines a period that limits whether the action runs.", + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "dsl": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL).", + "type": "string" + }, + "filters": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL) as defined in the `kbn-es-query` package.", + "items": { + "additionalProperties": false, + "properties": { + "$state": { + "additionalProperties": false, + "properties": { + "store": { + "description": "A filter can be either specific to an application context or applied globally.", + "enum": [ + "appState", + "globalState" + ], + "type": "string" + } + }, + "required": [ + "store" + ], + "type": "object" + }, + "meta": { + "additionalProperties": {}, + "type": "object" + }, + "query": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "meta" + ], + "type": "object" + }, + "type": "array" + }, + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql", + "filters" + ], + "type": "object" + }, + "timeframe": { + "additionalProperties": false, + "properties": { + "days": { + "description": "Defines the days of the week that the action can run, represented as an array of numbers. For example, `1` represents Monday. An empty array is equivalent to specifying all the days of the week.", + "items": { + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "type": "integer" + }, + "type": "array" + }, + "hours": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + }, + "start": { + "description": "The start of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + } + }, + "required": [ + "start", + "end" + ], + "type": "object" + }, + "timezone": { + "description": "The ISO time zone for the `hours` values. Values such as `UTC` and `UTC+1` also work but lack built-in daylight savings time support and are not recommended.", + "type": "string" + } + }, + "required": [ + "days", + "hours", + "timezone" + ], + "type": "object" + } + }, + "type": "object" + }, + "connector_type_id": { + "description": "The type of connector. This property appears in responses but cannot be set in requests.", + "type": "string" + }, + "frequency": { + "additionalProperties": false, + "properties": { + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "type": "string" + }, + "summary": { + "description": "Indicates whether the action is a summary.", + "type": "boolean" + }, + "throttle": { + "description": "The throttle interval, which defines how often an alert generates repeated actions. It is specified in seconds, minutes, hours, or days and is applicable only if 'notify_when' is set to 'onThrottleInterval'. NOTE: You cannot specify the throttle interval at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "summary", + "notify_when", + "throttle" + ], + "type": "object" + }, + "group": { + "description": "The group name, which affects when the action runs (for example, when the threshold is met or when the alert is recovered). Each rule type has a list of valid action group names. If you don't need to group actions, set to `default`.", + "type": "string" + }, + "id": { + "description": "The identifier for the connector saved object.", + "type": "string" + }, + "params": { + "additionalProperties": {}, + "description": "The parameters for the action, which are sent to the connector. The `params` are handled as Mustache templates and passed a default set of context.", + "type": "object" + }, + "use_alert_data_for_template": { + "description": "Indicates whether to use alert data as a template.", + "type": "boolean" + }, + "uuid": { + "description": "A universally unique identifier (UUID) for the action.", + "type": "string" + } + }, + "required": [ + "id", + "connector_type_id", + "params" + ], + "type": "object" + }, + "type": "array" + }, + "active_snoozes": { + "items": { + "description": "List of active snoozes for the rule.", + "type": "string" + }, + "type": "array" + }, + "alert_delay": { + "additionalProperties": false, + "description": "Indicates that an alert occurs only when the specified number of consecutive runs met the rule conditions.", + "properties": { + "active": { + "description": "The number of consecutive runs that must meet the rule conditions.", + "type": "number" + } + }, + "required": [ + "active" + ], + "type": "object" + }, + "api_key_created_by_user": { + "description": "Indicates whether the API key that is associated with the rule was created by the user.", + "nullable": true, + "type": "boolean" + }, + "api_key_owner": { + "description": "The owner of the API key that is associated with the rule and used to run background tasks.", + "nullable": true, + "type": "string" + }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" + } + }, + "type": "object" + }, + "consumer": { + "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", + "type": "string" + }, + "created_at": { + "description": "The date and time that the rule was created.", + "type": "string" + }, + "created_by": { + "description": "The identifier for the user that created the rule.", + "nullable": true, + "type": "string" + }, + "enabled": { + "description": "Indicates whether you want to run the rule on an interval basis after it is created.", + "type": "boolean" + }, + "execution_status": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "properties": { + "message": { + "description": "Error message.", + "type": "string" + }, + "reason": { + "description": "Reason for error.", + "enum": [ + "read", + "decrypt", + "execute", + "unknown", + "license", + "timeout", + "disabled", + "validate" + ], + "type": "string" + } + }, + "required": [ + "reason", + "message" + ], + "type": "object" + }, + "last_duration": { + "description": "Duration of last execution of the rule.", + "type": "number" + }, + "last_execution_date": { + "description": "The date and time when rule was executed last.", + "type": "string" + }, + "status": { + "description": "Status of rule execution.", + "enum": [ + "ok", + "active", + "error", + "warning", + "pending", + "unknown" + ], + "type": "string" + }, + "warning": { + "additionalProperties": false, + "properties": { + "message": { + "description": "Warning message.", + "type": "string" + }, + "reason": { + "description": "Reason for warning.", + "enum": [ + "maxExecutableActions", + "maxAlerts", + "maxQueuedActions", + "ruleExecution" + ], + "type": "string" + } + }, + "required": [ + "reason", + "message" + ], + "type": "object" + } + }, + "required": [ + "status", + "last_execution_date" + ], + "type": "object" + }, + "flapping": { + "additionalProperties": false, + "description": "When flapping detection is turned on, alerts that switch quickly between active and recovered states are identified as “flapping” and notifications are reduced.", + "nullable": true, + "properties": { + "enabled": { + "description": "Determines whether the rule can enter the flapping state. By default, rules can enter the flapping state.", + "type": "boolean" + }, + "look_back_window": { + "description": "The minimum number of runs in which the threshold must be met.", + "maximum": 20, + "minimum": 2, + "type": "number" + }, + "status_change_threshold": { + "description": "The minimum number of times an alert must switch states in the look back window.", + "maximum": 20, + "minimum": 2, + "type": "number" + } + }, + "required": [ + "look_back_window", + "status_change_threshold" + ], + "type": "object" + }, + "id": { + "description": "The identifier for the rule.", + "type": "string" + }, + "is_snoozed_until": { + "description": "The date when the rule will no longer be snoozed.", + "nullable": true, + "type": "string" + }, + "last_run": { + "additionalProperties": false, + "nullable": true, + "properties": { + "alerts_count": { + "additionalProperties": false, + "properties": { + "active": { + "description": "Number of active alerts during last run.", + "nullable": true, + "type": "number" + }, + "ignored": { + "description": "Number of ignored alerts during last run.", + "nullable": true, + "type": "number" + }, + "new": { + "description": "Number of new alerts during last run.", + "nullable": true, + "type": "number" + }, + "recovered": { + "description": "Number of recovered alerts during last run.", + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "outcome": { + "description": "Outcome of last run of the rule. Value could be succeeded, warning or failed.", + "enum": [ + "succeeded", + "warning", + "failed" + ], + "type": "string" + }, + "outcome_msg": { + "items": { + "description": "Outcome message generated during last rule run.", + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "outcome_order": { + "description": "Order of the outcome.", + "type": "number" + }, + "warning": { + "description": "Warning of last rule execution.", + "enum": [ + "read", + "decrypt", + "execute", + "unknown", + "license", + "timeout", + "disabled", + "validate", + "maxExecutableActions", + "maxAlerts", + "maxQueuedActions", + "ruleExecution" + ], + "nullable": true, + "type": "string" + } + }, + "required": [ + "outcome", + "alerts_count" + ], + "type": "object" + }, + "mapped_params": { + "additionalProperties": {}, + "type": "object" + }, + "monitoring": { + "additionalProperties": false, + "description": "Monitoring details of the rule.", + "properties": { + "run": { + "additionalProperties": false, + "description": "Rule run details.", + "properties": { + "calculated_metrics": { + "additionalProperties": false, + "description": "Calculation of different percentiles and success ratio.", + "properties": { + "p50": { + "type": "number" + }, + "p95": { + "type": "number" + }, + "p99": { + "type": "number" + }, + "success_ratio": { + "type": "number" + } + }, + "required": [ + "success_ratio" + ], + "type": "object" + }, + "history": { + "description": "History of the rule run.", + "items": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of the rule run.", + "type": "number" + }, + "outcome": { + "description": "Outcome of last run of the rule. Value could be succeeded, warning or failed.", + "enum": [ + "succeeded", + "warning", + "failed" + ], + "type": "string" + }, + "success": { + "description": "Indicates whether the rule run was successful.", + "type": "boolean" + }, + "timestamp": { + "description": "Time of rule run.", + "type": "number" + } + }, + "required": [ + "success", + "timestamp" + ], + "type": "object" + }, + "type": "array" + }, + "last_run": { + "additionalProperties": false, + "properties": { + "metrics": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of most recent rule run.", + "type": "number" + }, + "gap_duration_s": { + "description": "Duration in seconds of rule run gap.", + "nullable": true, + "type": "number" + }, + "gap_range": { + "additionalProperties": false, + "nullable": true, + "properties": { + "gte": { + "description": "End of the gap range.", + "type": "string" + }, + "lte": { + "description": "Start of the gap range.", + "type": "string" + } + }, + "required": [ + "lte", + "gte" + ], + "type": "object" + }, + "total_alerts_created": { + "description": "Total number of alerts created during last rule run.", + "nullable": true, + "type": "number" + }, + "total_alerts_detected": { + "description": "Total number of alerts detected during last rule run.", + "nullable": true, + "type": "number" + }, + "total_indexing_duration_ms": { + "description": "Total time spent indexing documents during last rule run in milliseconds.", + "nullable": true, + "type": "number" + }, + "total_search_duration_ms": { + "description": "Total time spent performing Elasticsearch searches as measured by Kibana; includes network latency and time spent serializing or deserializing the request and response.", + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "timestamp": { + "description": "Time of the most recent rule run.", + "type": "string" + } + }, + "required": [ + "timestamp", + "metrics" + ], + "type": "object" + } + }, + "required": [ + "history", + "calculated_metrics", + "last_run" + ], + "type": "object" + } + }, + "required": [ + "run" + ], + "type": "object" + }, + "mute_all": { + "description": "Indicates whether all alerts are muted.", + "type": "boolean" + }, + "muted_alert_ids": { + "items": { + "description": "List of identifiers of muted alerts. ", + "type": "string" + }, + "type": "array" + }, + "name": { + "description": " The name of the rule.", + "type": "string" + }, + "next_run": { + "description": "Date and time of the next run of the rule.", + "nullable": true, + "type": "string" + }, + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "nullable": true, + "type": "string" + }, + "params": { + "additionalProperties": {}, + "description": "The parameters for the rule.", + "type": "object" + }, + "revision": { + "description": "The rule revision number.", + "type": "number" + }, + "rule_type_id": { + "description": "The rule type identifier.", + "type": "string" + }, + "running": { + "description": "Indicates whether the rule is running.", + "nullable": true, + "type": "boolean" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "interval": { + "description": "The interval is specified in seconds, minutes, hours, or days.", + "type": "string" + } + }, + "required": [ + "interval" + ], + "type": "object" + }, + "scheduled_task_id": { + "description": "Identifier of the scheduled task.", + "type": "string" + }, + "snooze_schedule": { + "items": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of the rule snooze schedule.", + "type": "number" + }, + "id": { + "description": "Identifier of the rule snooze schedule.", + "type": "string" + }, + "rRule": { + "additionalProperties": false, + "properties": { + "byhour": { + "items": { + "description": "Indicates hours of the day to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byminute": { + "items": { + "description": "Indicates minutes of the hour to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bymonth": { + "items": { + "description": "Indicates months of the year that this rule should recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bymonthday": { + "items": { + "description": "Indicates the days of the month to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bysecond": { + "items": { + "description": "Indicates seconds of the day to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bysetpos": { + "items": { + "description": "A positive or negative integer affecting the nth day of the month. For example, -2 combined with `byweekday` of FR is 2nd to last Friday of the month. It is recommended to not set this manually and just use `byweekday`.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byweekday": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Indicates the days of the week to recur or else nth-day-of-month strings. For example, \"+2TU\" second Tuesday of month, \"-1FR\" last Friday of the month, which are internally converted to a `byweekday/bysetpos` combination." + }, + "nullable": true, + "type": "array" + }, + "byweekno": { + "items": { + "description": "Indicates number of the week hours to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byyearday": { + "items": { + "description": "Indicates the days of the year that this rule should recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "count": { + "description": "Number of times the rule should recur until it stops.", + "type": "number" + }, + "dtstart": { + "description": "Rule start date in Coordinated Universal Time (UTC).", + "type": "string" + }, + "freq": { + "description": "Indicates frequency of the rule. Options are YEARLY, MONTHLY, WEEKLY, DAILY.", + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6 + ], + "type": "integer" + }, + "interval": { + "description": "Indicates the interval of frequency. For example, 1 and YEARLY is every 1 year, 2 and WEEKLY is every 2 weeks.", + "type": "number" + }, + "tzid": { + "description": "Indicates timezone abbreviation.", + "type": "string" + }, + "until": { + "description": "Recur the rule until this date.", + "type": "string" + }, + "wkst": { + "description": "Indicates the start of week, defaults to Monday.", + "enum": [ + "MO", + "TU", + "WE", + "TH", + "FR", + "SA", + "SU" + ], + "type": "string" + } + }, + "required": [ + "dtstart", + "tzid" + ], + "type": "object" + }, + "skipRecurrences": { + "items": { + "description": "Skips recurrence of rule on this date.", + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "duration", + "rRule" + ], + "type": "object" + }, + "type": "array" + }, + "tags": { + "items": { + "description": "The tags for the rule.", + "type": "string" + }, + "type": "array" + }, + "throttle": { + "deprecated": true, + "description": "Deprecated in 8.13.0. Use the `throttle` property in the action `frequency` object instead. The throttle interval, which defines how often an alert generates repeated actions. NOTE: You cannot specify the throttle interval at both the rule and action level. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + }, + "updated_at": { + "description": "The date and time that the rule was updated most recently.", + "type": "string" + }, + "updated_by": { + "description": "The identifier for the user that updated this rule most recently.", + "nullable": true, + "type": "string" + }, + "view_in_app_relative_url": { + "description": "Relative URL to view rule in the app.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "enabled", + "name", + "tags", + "rule_type_id", + "consumer", + "schedule", + "actions", + "params", + "created_by", + "updated_by", + "created_at", + "updated_at", + "api_key_owner", + "mute_all", + "muted_alert_ids", + "execution_status", + "revision" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule with the given ID does not exist." + }, + "409": { + "description": "Indicates that the rule has already been updated by another user." + } + }, + "summary": "Update a rule", + "tags": [ + "alerting" + ] + } + }, + "/api/alerting/rule/{id}/_disable": { + "post": { + "operationId": "post-alerting-rule-id-disable", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the rule.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "nullable": true, + "properties": { + "untrack": { + "description": "Defines whether this rule's alerts should be untracked.", + "type": "boolean" + } + }, + "type": "object", + "x-oas-optional": true + } + } + } + }, + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule with the given ID does not exist." + } + }, + "summary": "Disable a rule", + "tags": [ + "alerting" + ] + } + }, + "/api/alerting/rule/{id}/_enable": { + "post": { + "operationId": "post-alerting-rule-id-enable", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the rule.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule with the given ID does not exist." + } + }, + "summary": "Enable a rule", + "tags": [ + "alerting" + ] + } + }, + "/api/alerting/rule/{id}/_mute_all": { + "post": { + "operationId": "post-alerting-rule-id-mute-all", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the rule.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule with the given ID does not exist." + } + }, + "summary": "Mute all alerts", + "tags": [ + "alerting" + ] + } + }, + "/api/alerting/rule/{id}/_unmute_all": { + "post": { + "operationId": "post-alerting-rule-id-unmute-all", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the rule.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule with the given ID does not exist." + } + }, + "summary": "Unmute all alerts", + "tags": [ + "alerting" + ] + } + }, + "/api/alerting/rule/{id}/_update_api_key": { + "post": { + "operationId": "post-alerting-rule-id-update-api-key", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the rule.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule with the given ID does not exist." + }, + "409": { + "description": "Indicates that the rule has already been updated by another user." + } + }, + "summary": "Update the API key for a rule", + "tags": [ + "alerting" + ] + } + }, + "/api/alerting/rule/{id}/snooze_schedule": { + "post": { + "description": "When you snooze a rule, the rule checks continue to run but alerts will not generate actions. You can snooze for a specified period of time and schedule single or recurring downtimes.", + "operationId": "post-alerting-rule-id-snooze-schedule", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "Identifier of the rule.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "schedule": { + "additionalProperties": false, + "properties": { + "custom": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "The duration of the schedule. It allows values in `` format. `` is one of `d`, `h`, `m`, or `s` for hours, minutes, seconds. For example: `1d`, `5h`, `30m`, `5000s`.", + "type": "string" + }, + "recurring": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end date of a recurring schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-04-01T00:00:00.000Z`.", + "type": "string" + }, + "every": { + "description": "The interval and frequency of a recurring schedule. It allows values in `` format. `` is one of `d`, `w`, `M`, or `y` for days, weeks, months, years. For example: `15d`, `2w`, `3m`, `1y`.", + "type": "string" + }, + "occurrences": { + "description": "The total number of recurrences of the schedule.", + "minimum": 1, + "type": "number" + }, + "onMonth": { + "description": "The specific months for a recurring schedule. Valid values are 1-12.", + "items": { + "maximum": 12, + "minimum": 1, + "type": "number" + }, + "minItems": 1, + "type": "array" + }, + "onMonthDay": { + "description": "The specific days of the month for a recurring schedule. Valid values are 1-31.", + "items": { + "maximum": 31, + "minimum": 1, + "type": "number" + }, + "minItems": 1, + "type": "array" + }, + "onWeekDay": { + "description": "The specific days of the week (`[MO,TU,WE,TH,FR,SA,SU]`) or nth day of month (`[+1MO, -3FR, +2WE, -4SA, -5SU]`) for a recurring schedule.", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "start": { + "description": "The start date and time of the schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-03-12T12:00:00.000Z`.", + "type": "string" + }, + "timezone": { + "description": "The timezone of the schedule. The default timezone is UTC.", + "type": "string" + } + }, + "required": [ + "start", + "duration" + ], + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "schedule" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "body": { + "additionalProperties": false, + "properties": { + "schedule": { + "additionalProperties": false, + "properties": { + "custom": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "The duration of the schedule. It allows values in `` format. `` is one of `d`, `h`, `m`, or `s` for hours, minutes, seconds. For example: `1d`, `5h`, `30m`, `5000s`.", + "type": "string" + }, + "recurring": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end date of a recurring schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-04-01T00:00:00.000Z`.", + "type": "string" + }, + "every": { + "description": "The interval and frequency of a recurring schedule. It allows values in `` format. `` is one of `d`, `w`, `M`, or `y` for days, weeks, months, years. For example: `15d`, `2w`, `3m`, `1y`.", + "type": "string" + }, + "occurrences": { + "description": "The total number of recurrences of the schedule.", + "minimum": 1, + "type": "number" + }, + "onMonth": { + "description": "The specific months for a recurring schedule. Valid values are 1-12.", + "items": { + "maximum": 12, + "minimum": 1, + "type": "number" + }, + "minItems": 1, + "type": "array" + }, + "onMonthDay": { + "description": "The specific days of the month for a recurring schedule. Valid values are 1-31.", + "items": { + "maximum": 31, + "minimum": 1, + "type": "number" + }, + "minItems": 1, + "type": "array" + }, + "onWeekDay": { + "description": "The specific days of the week (`[MO,TU,WE,TH,FR,SA,SU]`) or nth day of month (`[+1MO, -3FR, +2WE, -4SA, -5SU]`) for a recurring schedule.", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "start": { + "description": "The start date and time of the schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-03-12T12:00:00.000Z`.", + "type": "string" + }, + "timezone": { + "description": "The timezone of the schedule. The default timezone is UTC.", + "type": "string" + } + }, + "required": [ + "start", + "duration" + ], + "type": "object" + }, + "id": { + "description": "Identifier of the snooze schedule.", + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + }, + "required": [ + "schedule" + ], + "type": "object" + } + }, + "required": [ + "body" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule with the given id does not exist." + } + }, + "summary": "Schedule a snooze for the rule", + "tags": [ + "alerting" + ], + "x-state": "Generally available; added in 8.19.0" + } + }, + "/api/alerting/rule/{ruleId}/snooze_schedule/{scheduleId}": { + "delete": { + "operationId": "delete-alerting-rule-ruleid-snooze-schedule-scheduleid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the rule.", + "in": "path", + "name": "ruleId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "The identifier for the snooze schedule.", + "in": "path", + "name": "scheduleId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule with the given id does not exist." + } + }, + "summary": "Delete a snooze schedule for a rule", + "tags": [ + "alerting" + ], + "x-state": "Generally available; added in 8.19.0" + } + }, + "/api/alerting/rule/{rule_id}/alert/{alert_id}/_mute": { + "post": { + "operationId": "post-alerting-rule-rule-id-alert-alert-id-mute", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the rule.", + "in": "path", + "name": "rule_id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "The identifier for the alert.", + "in": "path", + "name": "alert_id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Whether to validate the existence of the alert.", + "in": "query", + "name": "validate_alerts_existence", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule or alert with the given ID does not exist." + } + }, + "summary": "Mute an alert", + "tags": [ + "alerting" + ] + } + }, + "/api/alerting/rule/{rule_id}/alert/{alert_id}/_unmute": { + "post": { + "operationId": "post-alerting-rule-rule-id-alert-alert-id-unmute", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the rule.", + "in": "path", + "name": "rule_id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "The identifier for the alert.", + "in": "path", + "name": "alert_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a rule or alert with the given ID does not exist." + } + }, + "summary": "Unmute an alert", + "tags": [ + "alerting" + ] + } + }, + "/api/alerting/rules/_find": { + "get": { + "operationId": "get-alerting-rules-find", + "parameters": [ + { + "description": "The number of rules to return per page.", + "in": "query", + "name": "per_page", + "required": false, + "schema": { + "default": 10, + "minimum": 0, + "type": "number" + } + }, + { + "description": "The page number to return.", + "in": "query", + "name": "page", + "required": false, + "schema": { + "default": 1, + "minimum": 1, + "type": "number" + } + }, + { + "description": "An Elasticsearch simple_query_string query that filters the objects in the response.", + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "The default operator to use for the simple_query_string.", + "in": "query", + "name": "default_search_operator", + "required": false, + "schema": { + "default": "OR", + "enum": [ + "OR", + "AND" + ], + "type": "string" + } + }, + { + "description": "The fields to perform the simple_query_string parsed query against.", + "in": "query", + "name": "search_fields", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + } + }, + { + "description": "Determines which field is used to sort the results. The field must exist in the `attributes` key of the response.", + "in": "query", + "name": "sort_field", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Determines the sort order.", + "in": "query", + "name": "sort_order", + "required": false, + "schema": { + "enum": [ + "asc", + "desc" + ], + "type": "string" + } + }, + { + "description": "Filters the rules that have a relation with the reference objects with a specific type and identifier.", + "in": "query", + "name": "has_reference", + "required": false, + "schema": { + "additionalProperties": false, + "nullable": true, + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "id" + ], + "type": "object" + } + }, + { + "description": "The fields to return in the `attributes` key of the response.", + "in": "query", + "name": "fields", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "string" + } + ] + } + }, + { + "description": "A KQL string that you filter with an attribute from your saved object. It should look like `savedObjectType.attributes.title: \"myTitle\"`. However, if you used a direct attribute of a saved object, such as `updatedAt`, you must define your filter, for example, `savedObjectType.updatedAt > 2018-12-22`.", + "in": "query", + "name": "filter", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "filter_consumers", + "required": false, + "schema": { + "items": { + "description": "List of consumers to filter.", + "type": "string" + }, + "type": "array" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "findConditionalActionRulesResponse": { + "description": "A response that contains information about an index threshold rule.", + "summary": "Index threshold rule", + "value": { + "data": [ + { + "actions": [ + { + "frequency": { + "notify_when": "onActionGroupChange", + "summary": false, + "throttle": null + }, + "group": "threshold met", + "id": "9dca3e00-74f5-11ed-9801-35303b735aef", + "params": { + "connector_type_id": ".server-log", + "level": "info", + "message": "Rule {{rule.name}} is active for group {{context.group}}:\n\n- Value: {{context.value}}\n- Conditions Met: {{context.conditions}} over {{rule.params.timeWindowSize}}{{rule.params.timeWindowUnit}}\n- Timestamp: {{context.date}}" + }, + "uuid": "1c7a1280-f28c-4e06-96b2-e4e5f05d1d61" + } + ], + "api_key_created_by_user": false, + "api_key_owner": "elastic", + "consumer": "alerts", + "created_at": "2022-12-05T23:40:33.132Z", + "created_by": "elastic", + "enabled": true, + "execution_status": { + "last_duration": 48, + "last_execution_date": "2022-12-06T01:44:23.983Z", + "status": "ok" + }, + "id": "3583a470-74f6-11ed-9801-35303b735aef", + "last_run": { + "alerts_count": { + "active": 0, + "ignored": 0, + "new": 0, + "recovered": 0 + }, + "outcome": "succeeded", + "outcome_msg": null, + "warning": null + }, + "mute_all": false, + "muted_alert_ids": [], + "name": "my alert", + "next_run": "2022-12-06T01:45:23.912Z", + "params": { + "aggField": "sheet.version", + "aggType": "avg", + "groupBy": "top", + "index": [ + "test-index" + ], + "termField": "name.keyword", + "termSize": 6, + "threshold": [ + 1000 + ], + "thresholdComparator": ">", + "timeField": "@timestamp", + "timeWindowSize": 5, + "timeWindowUnit": "m" + }, + "revision": 1, + "rule_type_id": ".index-threshold", + "schedule": { + "interval": "1m" + }, + "scheduled_task_id": "3583a470-74f6-11ed-9801-35303b735aef", + "tags": [ + "cpu" + ], + "throttle": null, + "updated_at": "2022-12-05T23:40:33.132Z", + "updated_by": "elastic" + } + ], + "page": 1, + "per_page": 10, + "total": 1 + } + }, + "findRulesResponse": { + "description": "A response that contains information about a security rule that has conditional actions.", + "summary": "Security rule", + "value": { + "data": [ + { + "actions": [ + { + "alerts_filter": { + "query": { + "filters": [ + { + "$state": { + "store": "appState" + }, + "meta": { + "alias": null, + "disabled": false, + "field": "client.geo.region_iso_code", + "index": "c4bdca79-e69e-4d80-82a1-e5192c621bea", + "key": "client.geo.region_iso_code", + "negate": false, + "params": { + "query": "CA-QC", + "type": "phrase" + } + }, + "query": { + "match_phrase": { + "client.geo.region_iso_code": "CA-QC" + } + } + } + ], + "kql": "" + }, + "timeframe": { + "days": [ + 7 + ], + "hours": { + "end": "17:00", + "start": "08:00" + }, + "timezone": "UTC" + } + }, + "connector_type_id": ".index", + "frequency": { + "notify_when": "onActiveAlert", + "summary": true, + "throttle": null + }, + "group": "default", + "id": "49eae970-f401-11ed-9f8e-399c75a2deeb", + "params": { + "documents": [ + { + "alert_id": { + "[object Object]": null + }, + "context_message": { + "[object Object]": null + }, + "rule_id": { + "[object Object]": null + }, + "rule_name": { + "[object Object]": null + } + } + ] + }, + "uuid": "1c7a1280-f28c-4e06-96b2-e4e5f05d1d61" + } + ], + "api_key_created_by_user": false, + "api_key_owner": "elastic", + "consumer": "siem", + "created_at": "2023-05-16T15:50:28.358Z", + "created_by": "elastic", + "enabled": true, + "execution_status": { + "last_duration": 166, + "last_execution_date": "2023-05-16T20:26:49.590Z", + "status": "ok" + }, + "id": "6107a8f0-f401-11ed-9f8e-399c75a2deeb", + "last_run": { + "alerts_count": { + "active": 0, + "ignored": 0, + "new": 0, + "recovered": 0 + }, + "outcome": "succeeded", + "outcome_msg": [ + "Rule execution completed successfully" + ], + "outcome_order": 0, + "warning": null + }, + "mute_all": false, + "muted_alert_ids": [], + "name": "security_rule", + "next_run": "2023-05-16T20:27:49.507Z", + "notify_when": null, + "params": { + "author": [], + "description": "A security threshold rule.", + "exceptionsList": [], + "falsePositives": [], + "filters": [], + "from": "now-3660s", + "immutable": false, + "index": [ + "kibana_sample_data_logs" + ], + "language": "kuery", + "license": "", + "maxSignals": 100, + "meta": { + "from": "1h", + "kibana_siem_app_url": "https://localhost:5601/app/security" + }, + "outputIndex": "", + "query": "*", + "references": [], + "riskScore": 21, + "riskScoreMapping": [], + "ruleId": "an_internal_rule_id", + "severity": "low", + "severityMapping": [], + "threat": [], + "threshold": { + "cardinality": [], + "field": [ + "bytes" + ], + "value": 1 + }, + "to": "now", + "type": "threshold", + "version": 1 + }, + "revision": 1, + "rule_type_id": "siem.thresholdRule", + "running": false, + "schedule": { + "interval": "1m" + }, + "scheduled_task_id": "6107a8f0-f401-11ed-9f8e-399c75a2deeb", + "tags": [], + "throttle": null, + "updated_at": "2023-05-16T20:25:42.559Z", + "updated_by": "elastic" + } + ], + "page": 1, + "per_page": 10, + "total": 1 + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "actions": { + "items": { + "additionalProperties": false, + "properties": { + "alerts_filter": { + "additionalProperties": false, + "description": "Defines a period that limits whether the action runs.", + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "dsl": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL).", + "type": "string" + }, + "filters": { + "description": "A filter written in Elasticsearch Query Domain Specific Language (DSL) as defined in the `kbn-es-query` package.", + "items": { + "additionalProperties": false, + "properties": { + "$state": { + "additionalProperties": false, + "properties": { + "store": { + "description": "A filter can be either specific to an application context or applied globally.", + "enum": [ + "appState", + "globalState" + ], + "type": "string" + } + }, + "required": [ + "store" + ], + "type": "object" + }, + "meta": { + "additionalProperties": {}, + "type": "object" + }, + "query": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "meta" + ], + "type": "object" + }, + "type": "array" + }, + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql", + "filters" + ], + "type": "object" + }, + "timeframe": { + "additionalProperties": false, + "properties": { + "days": { + "description": "Defines the days of the week that the action can run, represented as an array of numbers. For example, `1` represents Monday. An empty array is equivalent to specifying all the days of the week.", + "items": { + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "type": "integer" + }, + "type": "array" + }, + "hours": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + }, + "start": { + "description": "The start of the time frame in 24-hour notation (`hh:mm`).", + "type": "string" + } + }, + "required": [ + "start", + "end" + ], + "type": "object" + }, + "timezone": { + "description": "The ISO time zone for the `hours` values. Values such as `UTC` and `UTC+1` also work but lack built-in daylight savings time support and are not recommended.", + "type": "string" + } + }, + "required": [ + "days", + "hours", + "timezone" + ], + "type": "object" + } + }, + "type": "object" + }, + "connector_type_id": { + "description": "The type of connector. This property appears in responses but cannot be set in requests.", + "type": "string" + }, + "frequency": { + "additionalProperties": false, + "properties": { + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "type": "string" + }, + "summary": { + "description": "Indicates whether the action is a summary.", + "type": "boolean" + }, + "throttle": { + "description": "The throttle interval, which defines how often an alert generates repeated actions. It is specified in seconds, minutes, hours, or days and is applicable only if 'notify_when' is set to 'onThrottleInterval'. NOTE: You cannot specify the throttle interval at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "summary", + "notify_when", + "throttle" + ], + "type": "object" + }, + "group": { + "description": "The group name, which affects when the action runs (for example, when the threshold is met or when the alert is recovered). Each rule type has a list of valid action group names. If you don't need to group actions, set to `default`.", + "type": "string" + }, + "id": { + "description": "The identifier for the connector saved object.", + "type": "string" + }, + "params": { + "additionalProperties": {}, + "description": "The parameters for the action, which are sent to the connector. The `params` are handled as Mustache templates and passed a default set of context.", + "type": "object" + }, + "use_alert_data_for_template": { + "description": "Indicates whether to use alert data as a template.", + "type": "boolean" + }, + "uuid": { + "description": "A universally unique identifier (UUID) for the action.", + "type": "string" + } + }, + "required": [ + "id", + "connector_type_id", + "params" + ], + "type": "object" + }, + "type": "array" + }, + "active_snoozes": { + "items": { + "description": "List of active snoozes for the rule.", + "type": "string" + }, + "type": "array" + }, + "alert_delay": { + "additionalProperties": false, + "description": "Indicates that an alert occurs only when the specified number of consecutive runs met the rule conditions.", + "properties": { + "active": { + "description": "The number of consecutive runs that must meet the rule conditions.", + "type": "number" + } + }, + "required": [ + "active" + ], + "type": "object" + }, + "api_key_created_by_user": { + "description": "Indicates whether the API key that is associated with the rule was created by the user.", + "nullable": true, + "type": "boolean" + }, + "api_key_owner": { + "description": "The owner of the API key that is associated with the rule and used to run background tasks.", + "nullable": true, + "type": "string" + }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" + } + }, + "type": "object" + }, + "consumer": { + "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", + "type": "string" + }, + "created_at": { + "description": "The date and time that the rule was created.", + "type": "string" + }, + "created_by": { + "description": "The identifier for the user that created the rule.", + "nullable": true, + "type": "string" + }, + "enabled": { + "description": "Indicates whether you want to run the rule on an interval basis after it is created.", + "type": "boolean" + }, + "execution_status": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "properties": { + "message": { + "description": "Error message.", + "type": "string" + }, + "reason": { + "description": "Reason for error.", + "enum": [ + "read", + "decrypt", + "execute", + "unknown", + "license", + "timeout", + "disabled", + "validate" + ], + "type": "string" + } + }, + "required": [ + "reason", + "message" + ], + "type": "object" + }, + "last_duration": { + "description": "Duration of last execution of the rule.", + "type": "number" + }, + "last_execution_date": { + "description": "The date and time when rule was executed last.", + "type": "string" + }, + "status": { + "description": "Status of rule execution.", + "enum": [ + "ok", + "active", + "error", + "warning", + "pending", + "unknown" + ], + "type": "string" + }, + "warning": { + "additionalProperties": false, + "properties": { + "message": { + "description": "Warning message.", + "type": "string" + }, + "reason": { + "description": "Reason for warning.", + "enum": [ + "maxExecutableActions", + "maxAlerts", + "maxQueuedActions", + "ruleExecution" + ], + "type": "string" + } + }, + "required": [ + "reason", + "message" + ], + "type": "object" + } + }, + "required": [ + "status", + "last_execution_date" + ], + "type": "object" + }, + "flapping": { + "additionalProperties": false, + "description": "When flapping detection is turned on, alerts that switch quickly between active and recovered states are identified as “flapping” and notifications are reduced.", + "nullable": true, + "properties": { + "enabled": { + "description": "Determines whether the rule can enter the flapping state. By default, rules can enter the flapping state.", + "type": "boolean" + }, + "look_back_window": { + "description": "The minimum number of runs in which the threshold must be met.", + "maximum": 20, + "minimum": 2, + "type": "number" + }, + "status_change_threshold": { + "description": "The minimum number of times an alert must switch states in the look back window.", + "maximum": 20, + "minimum": 2, + "type": "number" + } + }, + "required": [ + "look_back_window", + "status_change_threshold" + ], + "type": "object" + }, + "id": { + "description": "The identifier for the rule.", + "type": "string" + }, + "is_snoozed_until": { + "description": "The date when the rule will no longer be snoozed.", + "nullable": true, + "type": "string" + }, + "last_run": { + "additionalProperties": false, + "nullable": true, + "properties": { + "alerts_count": { + "additionalProperties": false, + "properties": { + "active": { + "description": "Number of active alerts during last run.", + "nullable": true, + "type": "number" + }, + "ignored": { + "description": "Number of ignored alerts during last run.", + "nullable": true, + "type": "number" + }, + "new": { + "description": "Number of new alerts during last run.", + "nullable": true, + "type": "number" + }, + "recovered": { + "description": "Number of recovered alerts during last run.", + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "outcome": { + "description": "Outcome of last run of the rule. Value could be succeeded, warning or failed.", + "enum": [ + "succeeded", + "warning", + "failed" + ], + "type": "string" + }, + "outcome_msg": { + "items": { + "description": "Outcome message generated during last rule run.", + "type": "string" + }, + "nullable": true, + "type": "array" + }, + "outcome_order": { + "description": "Order of the outcome.", + "type": "number" + }, + "warning": { + "description": "Warning of last rule execution.", + "enum": [ + "read", + "decrypt", + "execute", + "unknown", + "license", + "timeout", + "disabled", + "validate", + "maxExecutableActions", + "maxAlerts", + "maxQueuedActions", + "ruleExecution" + ], + "nullable": true, + "type": "string" + } + }, + "required": [ + "outcome", + "alerts_count" + ], + "type": "object" + }, + "mapped_params": { + "additionalProperties": {}, + "type": "object" + }, + "monitoring": { + "additionalProperties": false, + "description": "Monitoring details of the rule.", + "properties": { + "run": { + "additionalProperties": false, + "description": "Rule run details.", + "properties": { + "calculated_metrics": { + "additionalProperties": false, + "description": "Calculation of different percentiles and success ratio.", + "properties": { + "p50": { + "type": "number" + }, + "p95": { + "type": "number" + }, + "p99": { + "type": "number" + }, + "success_ratio": { + "type": "number" + } + }, + "required": [ + "success_ratio" + ], + "type": "object" + }, + "history": { + "description": "History of the rule run.", + "items": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of the rule run.", + "type": "number" + }, + "outcome": { + "description": "Outcome of last run of the rule. Value could be succeeded, warning or failed.", + "enum": [ + "succeeded", + "warning", + "failed" + ], + "type": "string" + }, + "success": { + "description": "Indicates whether the rule run was successful.", + "type": "boolean" + }, + "timestamp": { + "description": "Time of rule run.", + "type": "number" + } + }, + "required": [ + "success", + "timestamp" + ], + "type": "object" + }, + "type": "array" + }, + "last_run": { + "additionalProperties": false, + "properties": { + "metrics": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of most recent rule run.", + "type": "number" + }, + "gap_duration_s": { + "description": "Duration in seconds of rule run gap.", + "nullable": true, + "type": "number" + }, + "gap_range": { + "additionalProperties": false, + "nullable": true, + "properties": { + "gte": { + "description": "End of the gap range.", + "type": "string" + }, + "lte": { + "description": "Start of the gap range.", + "type": "string" + } + }, + "required": [ + "lte", + "gte" + ], + "type": "object" + }, + "total_alerts_created": { + "description": "Total number of alerts created during last rule run.", + "nullable": true, + "type": "number" + }, + "total_alerts_detected": { + "description": "Total number of alerts detected during last rule run.", + "nullable": true, + "type": "number" + }, + "total_indexing_duration_ms": { + "description": "Total time spent indexing documents during last rule run in milliseconds.", + "nullable": true, + "type": "number" + }, + "total_search_duration_ms": { + "description": "Total time spent performing Elasticsearch searches as measured by Kibana; includes network latency and time spent serializing or deserializing the request and response.", + "nullable": true, + "type": "number" + } + }, + "type": "object" + }, + "timestamp": { + "description": "Time of the most recent rule run.", + "type": "string" + } + }, + "required": [ + "timestamp", + "metrics" + ], + "type": "object" + } + }, + "required": [ + "history", + "calculated_metrics", + "last_run" + ], + "type": "object" + } + }, + "required": [ + "run" + ], + "type": "object" + }, + "mute_all": { + "description": "Indicates whether all alerts are muted.", + "type": "boolean" + }, + "muted_alert_ids": { + "items": { + "description": "List of identifiers of muted alerts. ", + "type": "string" + }, + "type": "array" + }, + "name": { + "description": " The name of the rule.", + "type": "string" + }, + "next_run": { + "description": "Date and time of the next run of the rule.", + "nullable": true, + "type": "string" + }, + "notify_when": { + "description": "Indicates how often alerts generate actions. Valid values include: `onActionGroupChange`: Actions run when the alert status changes; `onActiveAlert`: Actions run when the alert becomes active and at each check interval while the rule conditions are met; `onThrottleInterval`: Actions run when the alert becomes active and at the interval specified in the throttle property while the rule conditions are met. NOTE: You cannot specify `notify_when` at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "enum": [ + "onActionGroupChange", + "onActiveAlert", + "onThrottleInterval" + ], + "nullable": true, + "type": "string" + }, + "params": { + "additionalProperties": {}, + "description": "The parameters for the rule.", + "type": "object" + }, + "revision": { + "description": "The rule revision number.", + "type": "number" + }, + "rule_type_id": { + "description": "The rule type identifier.", + "type": "string" + }, + "running": { + "description": "Indicates whether the rule is running.", + "nullable": true, + "type": "boolean" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "interval": { + "description": "The interval is specified in seconds, minutes, hours, or days.", + "type": "string" + } + }, + "required": [ + "interval" + ], + "type": "object" + }, + "scheduled_task_id": { + "description": "Identifier of the scheduled task.", + "type": "string" + }, + "snooze_schedule": { + "items": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "Duration of the rule snooze schedule.", + "type": "number" + }, + "id": { + "description": "Identifier of the rule snooze schedule.", + "type": "string" + }, + "rRule": { + "additionalProperties": false, + "properties": { + "byhour": { + "items": { + "description": "Indicates hours of the day to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byminute": { + "items": { + "description": "Indicates minutes of the hour to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bymonth": { + "items": { + "description": "Indicates months of the year that this rule should recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bymonthday": { + "items": { + "description": "Indicates the days of the month to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bysecond": { + "items": { + "description": "Indicates seconds of the day to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "bysetpos": { + "items": { + "description": "A positive or negative integer affecting the nth day of the month. For example, -2 combined with `byweekday` of FR is 2nd to last Friday of the month. It is recommended to not set this manually and just use `byweekday`.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byweekday": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "description": "Indicates the days of the week to recur or else nth-day-of-month strings. For example, \"+2TU\" second Tuesday of month, \"-1FR\" last Friday of the month, which are internally converted to a `byweekday/bysetpos` combination." + }, + "nullable": true, + "type": "array" + }, + "byweekno": { + "items": { + "description": "Indicates number of the week hours to recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "byyearday": { + "items": { + "description": "Indicates the days of the year that this rule should recur.", + "type": "number" + }, + "nullable": true, + "type": "array" + }, + "count": { + "description": "Number of times the rule should recur until it stops.", + "type": "number" + }, + "dtstart": { + "description": "Rule start date in Coordinated Universal Time (UTC).", + "type": "string" + }, + "freq": { + "description": "Indicates frequency of the rule. Options are YEARLY, MONTHLY, WEEKLY, DAILY.", + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6 + ], + "type": "integer" + }, + "interval": { + "description": "Indicates the interval of frequency. For example, 1 and YEARLY is every 1 year, 2 and WEEKLY is every 2 weeks.", + "type": "number" + }, + "tzid": { + "description": "Indicates timezone abbreviation.", + "type": "string" + }, + "until": { + "description": "Recur the rule until this date.", + "type": "string" + }, + "wkst": { + "description": "Indicates the start of week, defaults to Monday.", + "enum": [ + "MO", + "TU", + "WE", + "TH", + "FR", + "SA", + "SU" + ], + "type": "string" + } + }, + "required": [ + "dtstart", + "tzid" + ], + "type": "object" + }, + "skipRecurrences": { + "items": { + "description": "Skips recurrence of rule on this date.", + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "duration", + "rRule" + ], + "type": "object" + }, + "type": "array" + }, + "tags": { + "items": { + "description": "The tags for the rule.", + "type": "string" + }, + "type": "array" + }, + "throttle": { + "deprecated": true, + "description": "Deprecated in 8.13.0. Use the `throttle` property in the action `frequency` object instead. The throttle interval, which defines how often an alert generates repeated actions. NOTE: You cannot specify the throttle interval at both the rule and action level. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.", + "nullable": true, + "type": "string" + }, + "updated_at": { + "description": "The date and time that the rule was updated most recently.", + "type": "string" + }, + "updated_by": { + "description": "The identifier for the user that updated this rule most recently.", + "nullable": true, + "type": "string" + }, + "view_in_app_relative_url": { + "description": "Relative URL to view rule in the app.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "enabled", + "name", + "tags", + "rule_type_id", + "consumer", + "schedule", + "actions", + "params", + "created_by", + "updated_by", + "created_at", + "updated_at", + "api_key_owner", + "mute_all", + "muted_alert_ids", + "execution_status", + "revision" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + } + }, + "summary": "Get information about rules", + "tags": [ + "alerting" + ] + } + }, + "/api/fleet/agent_download_sources": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-read OR fleet-settings-read.", + "operationId": "get-fleet-agent-download-sources", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "host": { + "format": "uri", + "type": "string" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "description": "The ID of the proxy to use for this download source. See the proxies API for more information.", + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "id", + "name", + "host" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "page": { + "type": "number" + }, + "perPage": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "total", + "page", + "perPage" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get agent binary download sources", + "tags": [ + "Elastic Agent binary download sources" + ] + }, + "post": { + "description": "[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "post-fleet-agent-download-sources", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "host": { + "format": "uri", + "type": "string" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "description": "The ID of the proxy to use for this download source. See the proxies API for more information.", + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "name", + "host" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "host": { + "format": "uri", + "type": "string" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "description": "The ID of the proxy to use for this download source. See the proxies API for more information.", + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "id", + "name", + "host" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Create an agent binary download source", + "tags": [ + "Elastic Agent binary download sources" + ] + } + }, + "/api/fleet/agent_download_sources/{sourceId}": { + "delete": { + "description": "Delete an agent binary download source by ID.

[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "delete-fleet-agent-download-sources-sourceid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "sourceId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Delete an agent binary download source", + "tags": [ + "Elastic Agent binary download sources" + ] + }, + "get": { + "description": "Get an agent binary download source by ID.

[Required authorization] Route required privileges: fleet-agent-policies-read OR fleet-settings-read.", + "operationId": "get-fleet-agent-download-sources-sourceid", + "parameters": [ + { + "in": "path", + "name": "sourceId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "host": { + "format": "uri", + "type": "string" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "description": "The ID of the proxy to use for this download source. See the proxies API for more information.", + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "id", + "name", + "host" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get an agent binary download source", + "tags": [ + "Elastic Agent binary download sources" + ] + }, + "put": { + "description": "Update an agent binary download source by ID.

[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "put-fleet-agent-download-sources-sourceid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "sourceId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "host": { + "format": "uri", + "type": "string" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "description": "The ID of the proxy to use for this download source. See the proxies API for more information.", + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "name", + "host" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "host": { + "format": "uri", + "type": "string" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "description": "The ID of the proxy to use for this download source. See the proxies API for more information.", + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "id", + "name", + "host" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Update an agent binary download source", + "tags": [ + "Elastic Agent binary download sources" + ] + } + }, + "/api/fleet/agent_policies": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-read OR fleet-agents-read OR fleet-setup.", + "operationId": "get-fleet-agent-policies", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "perPage", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "sortField", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortOrder", + "required": false, + "schema": { + "enum": [ + "desc", + "asc" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "showUpgradeable", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "kuery", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "use withAgentCount instead", + "in": "query", + "name": "noAgentCount", + "required": false, + "schema": { + "deprecated": true, + "type": "boolean" + } + }, + { + "description": "get policies with agent count", + "in": "query", + "name": "withAgentCount", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "get full policies with package policies populated", + "in": "query", + "name": "full", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "format", + "required": false, + "schema": { + "enum": [ + "simplified", + "legacy" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "advanced_settings": { + "additionalProperties": false, + "properties": { + "agent_download_target_directory": { + "nullable": true + }, + "agent_download_timeout": { + "nullable": true + }, + "agent_internal": { + "nullable": true + }, + "agent_limits_go_max_procs": { + "nullable": true + }, + "agent_logging_files_interval": { + "nullable": true + }, + "agent_logging_files_keepfiles": { + "nullable": true + }, + "agent_logging_files_rotateeverybytes": { + "nullable": true + }, + "agent_logging_level": { + "nullable": true + }, + "agent_logging_metrics_period": { + "nullable": true + }, + "agent_logging_to_files": { + "nullable": true + }, + "agent_monitoring_runtime_experimental": { + "nullable": true + } + }, + "type": "object" + }, + "agent_features": { + "items": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "enabled" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "agentless": { + "additionalProperties": false, + "properties": { + "cloud_connectors": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "target_csp": { + "enum": [ + "aws", + "azure", + "gcp" + ], + "type": "string" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "resources": { + "additionalProperties": false, + "properties": { + "requests": { + "additionalProperties": false, + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "agents": { + "type": "number" + }, + "data_output_id": { + "nullable": true, + "type": "string" + }, + "description": { + "type": "string" + }, + "download_source_id": { + "nullable": true, + "type": "string" + }, + "fips_agents": { + "type": "number" + }, + "fleet_server_host_id": { + "nullable": true, + "type": "string" + }, + "global_data_tags": { + "description": "User defined data tags that are added to all of the inputs. The values can be strings or numbers.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "has_agent_version_conditions": { + "type": "boolean" + }, + "has_fleet_server": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "inactivity_timeout": { + "default": 1209600, + "minimum": 0, + "type": "number" + }, + "is_default": { + "type": "boolean" + }, + "is_default_fleet_server": { + "type": "boolean" + }, + "is_managed": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "is_protected": { + "description": "Indicates whether the agent policy has tamper protection enabled. Default false.", + "type": "boolean" + }, + "keep_monitoring_alive": { + "default": false, + "description": "When set to true, monitoring will be enabled but logs/metrics collection will be disabled", + "nullable": true, + "type": "boolean" + }, + "monitoring_diagnostics": { + "additionalProperties": false, + "properties": { + "limit": { + "additionalProperties": false, + "properties": { + "burst": { + "type": "number" + }, + "interval": { + "type": "string" + } + }, + "type": "object" + }, + "uploader": { + "additionalProperties": false, + "properties": { + "init_dur": { + "type": "string" + }, + "max_dur": { + "type": "string" + }, + "max_retries": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "monitoring_enabled": { + "items": { + "enum": [ + "logs", + "metrics", + "traces" + ], + "type": "string" + }, + "maxItems": 3, + "type": "array" + }, + "monitoring_http": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "port": { + "maximum": 65353, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "monitoring_output_id": { + "nullable": true, + "type": "string" + }, + "monitoring_pprof_enabled": { + "type": "boolean" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "namespace": { + "minLength": 1, + "type": "string" + }, + "overrides": { + "additionalProperties": {}, + "description": "Override settings that are defined in the agent policy. Input settings cannot be overridden. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "type": "object" + }, + "package_policies": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "description": "This field is present only when retrieving a single agent policy, or when retrieving a list of agent policies with the ?full=true parameter", + "items": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + ] + }, + "required_versions": { + "items": { + "additionalProperties": false, + "properties": { + "percentage": { + "description": "Target percentage of agents to auto upgrade", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "version": { + "description": "Target version for automatic agent upgrade", + "type": "string" + } + }, + "required": [ + "version", + "percentage" + ], + "type": "object" + }, + "maxItems": 100, + "nullable": true, + "type": "array" + }, + "revision": { + "type": "number" + }, + "schema_version": { + "type": "string" + }, + "space_ids": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "status": { + "enum": [ + "active", + "inactive" + ], + "type": "string" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the agent policy supports agentless integrations.", + "nullable": true, + "type": "boolean" + }, + "unenroll_timeout": { + "minimum": 0, + "type": "number" + }, + "unprivileged_agents": { + "type": "number" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "namespace", + "is_protected", + "status", + "updated_at", + "updated_by", + "revision" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "page": { + "type": "number" + }, + "perPage": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "total", + "page", + "perPage" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get agent policies", + "tags": [ + "Elastic Agent policies" + ] + }, + "post": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-all.", + "operationId": "post-fleet-agent-policies", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "query", + "name": "sys_monitoring", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "advanced_settings": { + "additionalProperties": false, + "properties": { + "agent_download_target_directory": { + "nullable": true + }, + "agent_download_timeout": { + "nullable": true + }, + "agent_internal": { + "nullable": true + }, + "agent_limits_go_max_procs": { + "nullable": true + }, + "agent_logging_files_interval": { + "nullable": true + }, + "agent_logging_files_keepfiles": { + "nullable": true + }, + "agent_logging_files_rotateeverybytes": { + "nullable": true + }, + "agent_logging_level": { + "nullable": true + }, + "agent_logging_metrics_period": { + "nullable": true + }, + "agent_logging_to_files": { + "nullable": true + }, + "agent_monitoring_runtime_experimental": { + "nullable": true + } + }, + "type": "object" + }, + "agent_features": { + "items": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "enabled" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "agentless": { + "additionalProperties": false, + "properties": { + "cloud_connectors": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "target_csp": { + "enum": [ + "aws", + "azure", + "gcp" + ], + "type": "string" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "resources": { + "additionalProperties": false, + "properties": { + "requests": { + "additionalProperties": false, + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "data_output_id": { + "nullable": true, + "type": "string" + }, + "description": { + "type": "string" + }, + "download_source_id": { + "nullable": true, + "type": "string" + }, + "fleet_server_host_id": { + "nullable": true, + "type": "string" + }, + "force": { + "type": "boolean" + }, + "global_data_tags": { + "description": "User defined data tags that are added to all of the inputs. The values can be strings or numbers.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "has_agent_version_conditions": { + "type": "boolean" + }, + "has_fleet_server": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "inactivity_timeout": { + "default": 1209600, + "minimum": 0, + "type": "number" + }, + "is_default": { + "type": "boolean" + }, + "is_default_fleet_server": { + "type": "boolean" + }, + "is_managed": { + "type": "boolean" + }, + "is_protected": { + "type": "boolean" + }, + "keep_monitoring_alive": { + "default": false, + "description": "When set to true, monitoring will be enabled but logs/metrics collection will be disabled", + "nullable": true, + "type": "boolean" + }, + "monitoring_diagnostics": { + "additionalProperties": false, + "properties": { + "limit": { + "additionalProperties": false, + "properties": { + "burst": { + "type": "number" + }, + "interval": { + "type": "string" + } + }, + "type": "object" + }, + "uploader": { + "additionalProperties": false, + "properties": { + "init_dur": { + "type": "string" + }, + "max_dur": { + "type": "string" + }, + "max_retries": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "monitoring_enabled": { + "items": { + "enum": [ + "logs", + "metrics", + "traces" + ], + "type": "string" + }, + "maxItems": 3, + "type": "array" + }, + "monitoring_http": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "port": { + "maximum": 65353, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "monitoring_output_id": { + "nullable": true, + "type": "string" + }, + "monitoring_pprof_enabled": { + "type": "boolean" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "namespace": { + "minLength": 1, + "type": "string" + }, + "overrides": { + "additionalProperties": {}, + "description": "Override settings that are defined in the agent policy. Input settings cannot be overridden. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "type": "object" + }, + "required_versions": { + "items": { + "additionalProperties": false, + "properties": { + "percentage": { + "description": "Target percentage of agents to auto upgrade", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "version": { + "description": "Target version for automatic agent upgrade", + "type": "string" + } + }, + "required": [ + "version", + "percentage" + ], + "type": "object" + }, + "maxItems": 100, + "nullable": true, + "type": "array" + }, + "space_ids": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "deprecated": true, + "description": "Indicates whether the agent policy supports agentless integrations. Deprecated in favor of the Fleet agentless policies API.", + "nullable": true, + "type": "boolean" + }, + "unenroll_timeout": { + "minimum": 0, + "type": "number" + } + }, + "required": [ + "name", + "namespace" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "advanced_settings": { + "additionalProperties": false, + "properties": { + "agent_download_target_directory": { + "nullable": true + }, + "agent_download_timeout": { + "nullable": true + }, + "agent_internal": { + "nullable": true + }, + "agent_limits_go_max_procs": { + "nullable": true + }, + "agent_logging_files_interval": { + "nullable": true + }, + "agent_logging_files_keepfiles": { + "nullable": true + }, + "agent_logging_files_rotateeverybytes": { + "nullable": true + }, + "agent_logging_level": { + "nullable": true + }, + "agent_logging_metrics_period": { + "nullable": true + }, + "agent_logging_to_files": { + "nullable": true + }, + "agent_monitoring_runtime_experimental": { + "nullable": true + } + }, + "type": "object" + }, + "agent_features": { + "items": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "enabled" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "agentless": { + "additionalProperties": false, + "properties": { + "cloud_connectors": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "target_csp": { + "enum": [ + "aws", + "azure", + "gcp" + ], + "type": "string" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "resources": { + "additionalProperties": false, + "properties": { + "requests": { + "additionalProperties": false, + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "agents": { + "type": "number" + }, + "data_output_id": { + "nullable": true, + "type": "string" + }, + "description": { + "type": "string" + }, + "download_source_id": { + "nullable": true, + "type": "string" + }, + "fips_agents": { + "type": "number" + }, + "fleet_server_host_id": { + "nullable": true, + "type": "string" + }, + "global_data_tags": { + "description": "User defined data tags that are added to all of the inputs. The values can be strings or numbers.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "has_agent_version_conditions": { + "type": "boolean" + }, + "has_fleet_server": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "inactivity_timeout": { + "default": 1209600, + "minimum": 0, + "type": "number" + }, + "is_default": { + "type": "boolean" + }, + "is_default_fleet_server": { + "type": "boolean" + }, + "is_managed": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "is_protected": { + "description": "Indicates whether the agent policy has tamper protection enabled. Default false.", + "type": "boolean" + }, + "keep_monitoring_alive": { + "default": false, + "description": "When set to true, monitoring will be enabled but logs/metrics collection will be disabled", + "nullable": true, + "type": "boolean" + }, + "monitoring_diagnostics": { + "additionalProperties": false, + "properties": { + "limit": { + "additionalProperties": false, + "properties": { + "burst": { + "type": "number" + }, + "interval": { + "type": "string" + } + }, + "type": "object" + }, + "uploader": { + "additionalProperties": false, + "properties": { + "init_dur": { + "type": "string" + }, + "max_dur": { + "type": "string" + }, + "max_retries": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "monitoring_enabled": { + "items": { + "enum": [ + "logs", + "metrics", + "traces" + ], + "type": "string" + }, + "maxItems": 3, + "type": "array" + }, + "monitoring_http": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "port": { + "maximum": 65353, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "monitoring_output_id": { + "nullable": true, + "type": "string" + }, + "monitoring_pprof_enabled": { + "type": "boolean" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "namespace": { + "minLength": 1, + "type": "string" + }, + "overrides": { + "additionalProperties": {}, + "description": "Override settings that are defined in the agent policy. Input settings cannot be overridden. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "type": "object" + }, + "package_policies": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "description": "This field is present only when retrieving a single agent policy, or when retrieving a list of agent policies with the ?full=true parameter", + "items": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + ] + }, + "required_versions": { + "items": { + "additionalProperties": false, + "properties": { + "percentage": { + "description": "Target percentage of agents to auto upgrade", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "version": { + "description": "Target version for automatic agent upgrade", + "type": "string" + } + }, + "required": [ + "version", + "percentage" + ], + "type": "object" + }, + "maxItems": 100, + "nullable": true, + "type": "array" + }, + "revision": { + "type": "number" + }, + "schema_version": { + "type": "string" + }, + "space_ids": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "status": { + "enum": [ + "active", + "inactive" + ], + "type": "string" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the agent policy supports agentless integrations.", + "nullable": true, + "type": "boolean" + }, + "unenroll_timeout": { + "minimum": 0, + "type": "number" + }, + "unprivileged_agents": { + "type": "number" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "namespace", + "is_protected", + "status", + "updated_at", + "updated_by", + "revision" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Create an agent policy", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/agent_policies/_bulk_get": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-read OR fleet-agents-read OR fleet-setup.", + "operationId": "post-fleet-agent-policies-bulk-get", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "query", + "name": "format", + "required": false, + "schema": { + "enum": [ + "simplified", + "legacy" + ], + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "full": { + "description": "get full policies with package policies populated", + "type": "boolean" + }, + "ids": { + "description": "list of package policy ids", + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ignoreMissing": { + "type": "boolean" + } + }, + "required": [ + "ids" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "advanced_settings": { + "additionalProperties": false, + "properties": { + "agent_download_target_directory": { + "nullable": true + }, + "agent_download_timeout": { + "nullable": true + }, + "agent_internal": { + "nullable": true + }, + "agent_limits_go_max_procs": { + "nullable": true + }, + "agent_logging_files_interval": { + "nullable": true + }, + "agent_logging_files_keepfiles": { + "nullable": true + }, + "agent_logging_files_rotateeverybytes": { + "nullable": true + }, + "agent_logging_level": { + "nullable": true + }, + "agent_logging_metrics_period": { + "nullable": true + }, + "agent_logging_to_files": { + "nullable": true + }, + "agent_monitoring_runtime_experimental": { + "nullable": true + } + }, + "type": "object" + }, + "agent_features": { + "items": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "enabled" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "agentless": { + "additionalProperties": false, + "properties": { + "cloud_connectors": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "target_csp": { + "enum": [ + "aws", + "azure", + "gcp" + ], + "type": "string" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "resources": { + "additionalProperties": false, + "properties": { + "requests": { + "additionalProperties": false, + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "agents": { + "type": "number" + }, + "data_output_id": { + "nullable": true, + "type": "string" + }, + "description": { + "type": "string" + }, + "download_source_id": { + "nullable": true, + "type": "string" + }, + "fips_agents": { + "type": "number" + }, + "fleet_server_host_id": { + "nullable": true, + "type": "string" + }, + "global_data_tags": { + "description": "User defined data tags that are added to all of the inputs. The values can be strings or numbers.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "has_agent_version_conditions": { + "type": "boolean" + }, + "has_fleet_server": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "inactivity_timeout": { + "default": 1209600, + "minimum": 0, + "type": "number" + }, + "is_default": { + "type": "boolean" + }, + "is_default_fleet_server": { + "type": "boolean" + }, + "is_managed": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "is_protected": { + "description": "Indicates whether the agent policy has tamper protection enabled. Default false.", + "type": "boolean" + }, + "keep_monitoring_alive": { + "default": false, + "description": "When set to true, monitoring will be enabled but logs/metrics collection will be disabled", + "nullable": true, + "type": "boolean" + }, + "monitoring_diagnostics": { + "additionalProperties": false, + "properties": { + "limit": { + "additionalProperties": false, + "properties": { + "burst": { + "type": "number" + }, + "interval": { + "type": "string" + } + }, + "type": "object" + }, + "uploader": { + "additionalProperties": false, + "properties": { + "init_dur": { + "type": "string" + }, + "max_dur": { + "type": "string" + }, + "max_retries": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "monitoring_enabled": { + "items": { + "enum": [ + "logs", + "metrics", + "traces" + ], + "type": "string" + }, + "maxItems": 3, + "type": "array" + }, + "monitoring_http": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "port": { + "maximum": 65353, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "monitoring_output_id": { + "nullable": true, + "type": "string" + }, + "monitoring_pprof_enabled": { + "type": "boolean" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "namespace": { + "minLength": 1, + "type": "string" + }, + "overrides": { + "additionalProperties": {}, + "description": "Override settings that are defined in the agent policy. Input settings cannot be overridden. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "type": "object" + }, + "package_policies": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "description": "This field is present only when retrieving a single agent policy, or when retrieving a list of agent policies with the ?full=true parameter", + "items": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + ] + }, + "required_versions": { + "items": { + "additionalProperties": false, + "properties": { + "percentage": { + "description": "Target percentage of agents to auto upgrade", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "version": { + "description": "Target version for automatic agent upgrade", + "type": "string" + } + }, + "required": [ + "version", + "percentage" + ], + "type": "object" + }, + "maxItems": 100, + "nullable": true, + "type": "array" + }, + "revision": { + "type": "number" + }, + "schema_version": { + "type": "string" + }, + "space_ids": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "status": { + "enum": [ + "active", + "inactive" + ], + "type": "string" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the agent policy supports agentless integrations.", + "nullable": true, + "type": "boolean" + }, + "unenroll_timeout": { + "minimum": 0, + "type": "number" + }, + "unprivileged_agents": { + "type": "number" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "namespace", + "is_protected", + "status", + "updated_at", + "updated_by", + "revision" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk get agent policies", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/agent_policies/delete": { + "post": { + "description": "Delete an agent policy by ID.

[Required authorization] Route required privileges: fleet-agent-policies-all.", + "operationId": "post-fleet-agent-policies-delete", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "agentPolicyId": { + "type": "string" + }, + "force": { + "description": "bypass validation checks that can prevent agent policy deletion", + "type": "boolean" + } + }, + "required": [ + "agentPolicyId" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Delete an agent policy", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/agent_policies/outputs": { + "post": { + "description": "Get a list of outputs associated with agent policies.

[Required authorization] Route required privileges: fleet-agent-policies-read AND fleet-settings-read.", + "operationId": "post-fleet-agent-policies-outputs", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "ids": { + "description": "list of package policy ids", + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + } + }, + "required": [ + "ids" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "agentPolicyId": { + "type": "string" + }, + "data": { + "additionalProperties": false, + "properties": { + "integrations": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "integrationPolicyName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "pkgName": { + "type": "string" + } + }, + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "output": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + } + }, + "required": [ + "output" + ], + "type": "object" + }, + "monitoring": { + "additionalProperties": false, + "properties": { + "output": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + } + }, + "required": [ + "output" + ], + "type": "object" + } + }, + "required": [ + "monitoring", + "data" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get outputs for agent policies", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/agent_policies/{agentPolicyId}": { + "get": { + "description": "Get an agent policy by ID.

[Required authorization] Route required privileges: fleet-agent-policies-read OR fleet-agents-read OR fleet-setup.", + "operationId": "get-fleet-agent-policies-agentpolicyid", + "parameters": [ + { + "in": "path", + "name": "agentPolicyId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "format", + "required": false, + "schema": { + "enum": [ + "simplified", + "legacy" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "advanced_settings": { + "additionalProperties": false, + "properties": { + "agent_download_target_directory": { + "nullable": true + }, + "agent_download_timeout": { + "nullable": true + }, + "agent_internal": { + "nullable": true + }, + "agent_limits_go_max_procs": { + "nullable": true + }, + "agent_logging_files_interval": { + "nullable": true + }, + "agent_logging_files_keepfiles": { + "nullable": true + }, + "agent_logging_files_rotateeverybytes": { + "nullable": true + }, + "agent_logging_level": { + "nullable": true + }, + "agent_logging_metrics_period": { + "nullable": true + }, + "agent_logging_to_files": { + "nullable": true + }, + "agent_monitoring_runtime_experimental": { + "nullable": true + } + }, + "type": "object" + }, + "agent_features": { + "items": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "enabled" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "agentless": { + "additionalProperties": false, + "properties": { + "cloud_connectors": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "target_csp": { + "enum": [ + "aws", + "azure", + "gcp" + ], + "type": "string" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "resources": { + "additionalProperties": false, + "properties": { + "requests": { + "additionalProperties": false, + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "agents": { + "type": "number" + }, + "data_output_id": { + "nullable": true, + "type": "string" + }, + "description": { + "type": "string" + }, + "download_source_id": { + "nullable": true, + "type": "string" + }, + "fips_agents": { + "type": "number" + }, + "fleet_server_host_id": { + "nullable": true, + "type": "string" + }, + "global_data_tags": { + "description": "User defined data tags that are added to all of the inputs. The values can be strings or numbers.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "has_agent_version_conditions": { + "type": "boolean" + }, + "has_fleet_server": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "inactivity_timeout": { + "default": 1209600, + "minimum": 0, + "type": "number" + }, + "is_default": { + "type": "boolean" + }, + "is_default_fleet_server": { + "type": "boolean" + }, + "is_managed": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "is_protected": { + "description": "Indicates whether the agent policy has tamper protection enabled. Default false.", + "type": "boolean" + }, + "keep_monitoring_alive": { + "default": false, + "description": "When set to true, monitoring will be enabled but logs/metrics collection will be disabled", + "nullable": true, + "type": "boolean" + }, + "monitoring_diagnostics": { + "additionalProperties": false, + "properties": { + "limit": { + "additionalProperties": false, + "properties": { + "burst": { + "type": "number" + }, + "interval": { + "type": "string" + } + }, + "type": "object" + }, + "uploader": { + "additionalProperties": false, + "properties": { + "init_dur": { + "type": "string" + }, + "max_dur": { + "type": "string" + }, + "max_retries": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "monitoring_enabled": { + "items": { + "enum": [ + "logs", + "metrics", + "traces" + ], + "type": "string" + }, + "maxItems": 3, + "type": "array" + }, + "monitoring_http": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "port": { + "maximum": 65353, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "monitoring_output_id": { + "nullable": true, + "type": "string" + }, + "monitoring_pprof_enabled": { + "type": "boolean" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "namespace": { + "minLength": 1, + "type": "string" + }, + "overrides": { + "additionalProperties": {}, + "description": "Override settings that are defined in the agent policy. Input settings cannot be overridden. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "type": "object" + }, + "package_policies": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "description": "This field is present only when retrieving a single agent policy, or when retrieving a list of agent policies with the ?full=true parameter", + "items": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + ] + }, + "required_versions": { + "items": { + "additionalProperties": false, + "properties": { + "percentage": { + "description": "Target percentage of agents to auto upgrade", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "version": { + "description": "Target version for automatic agent upgrade", + "type": "string" + } + }, + "required": [ + "version", + "percentage" + ], + "type": "object" + }, + "maxItems": 100, + "nullable": true, + "type": "array" + }, + "revision": { + "type": "number" + }, + "schema_version": { + "type": "string" + }, + "space_ids": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "status": { + "enum": [ + "active", + "inactive" + ], + "type": "string" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the agent policy supports agentless integrations.", + "nullable": true, + "type": "boolean" + }, + "unenroll_timeout": { + "minimum": 0, + "type": "number" + }, + "unprivileged_agents": { + "type": "number" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "namespace", + "is_protected", + "status", + "updated_at", + "updated_by", + "revision" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get an agent policy", + "tags": [ + "Elastic Agent policies" + ] + }, + "put": { + "description": "Update an agent policy by ID.

[Required authorization] Route required privileges: fleet-agent-policies-all.", + "operationId": "put-fleet-agent-policies-agentpolicyid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "agentPolicyId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "format", + "required": false, + "schema": { + "enum": [ + "simplified", + "legacy" + ], + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "advanced_settings": { + "additionalProperties": false, + "properties": { + "agent_download_target_directory": { + "nullable": true + }, + "agent_download_timeout": { + "nullable": true + }, + "agent_internal": { + "nullable": true + }, + "agent_limits_go_max_procs": { + "nullable": true + }, + "agent_logging_files_interval": { + "nullable": true + }, + "agent_logging_files_keepfiles": { + "nullable": true + }, + "agent_logging_files_rotateeverybytes": { + "nullable": true + }, + "agent_logging_level": { + "nullable": true + }, + "agent_logging_metrics_period": { + "nullable": true + }, + "agent_logging_to_files": { + "nullable": true + }, + "agent_monitoring_runtime_experimental": { + "nullable": true + } + }, + "type": "object" + }, + "agent_features": { + "items": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "enabled" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "agentless": { + "additionalProperties": false, + "properties": { + "cloud_connectors": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "target_csp": { + "enum": [ + "aws", + "azure", + "gcp" + ], + "type": "string" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "resources": { + "additionalProperties": false, + "properties": { + "requests": { + "additionalProperties": false, + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "bumpRevision": { + "type": "boolean" + }, + "data_output_id": { + "nullable": true, + "type": "string" + }, + "description": { + "type": "string" + }, + "download_source_id": { + "nullable": true, + "type": "string" + }, + "fleet_server_host_id": { + "nullable": true, + "type": "string" + }, + "force": { + "type": "boolean" + }, + "global_data_tags": { + "description": "User defined data tags that are added to all of the inputs. The values can be strings or numbers.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "has_agent_version_conditions": { + "type": "boolean" + }, + "has_fleet_server": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "inactivity_timeout": { + "default": 1209600, + "minimum": 0, + "type": "number" + }, + "is_default": { + "type": "boolean" + }, + "is_default_fleet_server": { + "type": "boolean" + }, + "is_managed": { + "type": "boolean" + }, + "is_protected": { + "type": "boolean" + }, + "keep_monitoring_alive": { + "default": false, + "description": "When set to true, monitoring will be enabled but logs/metrics collection will be disabled", + "nullable": true, + "type": "boolean" + }, + "monitoring_diagnostics": { + "additionalProperties": false, + "properties": { + "limit": { + "additionalProperties": false, + "properties": { + "burst": { + "type": "number" + }, + "interval": { + "type": "string" + } + }, + "type": "object" + }, + "uploader": { + "additionalProperties": false, + "properties": { + "init_dur": { + "type": "string" + }, + "max_dur": { + "type": "string" + }, + "max_retries": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "monitoring_enabled": { + "items": { + "enum": [ + "logs", + "metrics", + "traces" + ], + "type": "string" + }, + "maxItems": 3, + "type": "array" + }, + "monitoring_http": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "port": { + "maximum": 65353, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "monitoring_output_id": { + "nullable": true, + "type": "string" + }, + "monitoring_pprof_enabled": { + "type": "boolean" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "namespace": { + "minLength": 1, + "type": "string" + }, + "overrides": { + "additionalProperties": {}, + "description": "Override settings that are defined in the agent policy. Input settings cannot be overridden. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "type": "object" + }, + "required_versions": { + "items": { + "additionalProperties": false, + "properties": { + "percentage": { + "description": "Target percentage of agents to auto upgrade", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "version": { + "description": "Target version for automatic agent upgrade", + "type": "string" + } + }, + "required": [ + "version", + "percentage" + ], + "type": "object" + }, + "maxItems": 100, + "nullable": true, + "type": "array" + }, + "space_ids": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "deprecated": true, + "description": "Indicates whether the agent policy supports agentless integrations. Deprecated in favor of the Fleet agentless policies API.", + "nullable": true, + "type": "boolean" + }, + "unenroll_timeout": { + "minimum": 0, + "type": "number" + } + }, + "required": [ + "name", + "namespace" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "advanced_settings": { + "additionalProperties": false, + "properties": { + "agent_download_target_directory": { + "nullable": true + }, + "agent_download_timeout": { + "nullable": true + }, + "agent_internal": { + "nullable": true + }, + "agent_limits_go_max_procs": { + "nullable": true + }, + "agent_logging_files_interval": { + "nullable": true + }, + "agent_logging_files_keepfiles": { + "nullable": true + }, + "agent_logging_files_rotateeverybytes": { + "nullable": true + }, + "agent_logging_level": { + "nullable": true + }, + "agent_logging_metrics_period": { + "nullable": true + }, + "agent_logging_to_files": { + "nullable": true + }, + "agent_monitoring_runtime_experimental": { + "nullable": true + } + }, + "type": "object" + }, + "agent_features": { + "items": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "enabled" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "agentless": { + "additionalProperties": false, + "properties": { + "cloud_connectors": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "target_csp": { + "enum": [ + "aws", + "azure", + "gcp" + ], + "type": "string" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "resources": { + "additionalProperties": false, + "properties": { + "requests": { + "additionalProperties": false, + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "agents": { + "type": "number" + }, + "data_output_id": { + "nullable": true, + "type": "string" + }, + "description": { + "type": "string" + }, + "download_source_id": { + "nullable": true, + "type": "string" + }, + "fips_agents": { + "type": "number" + }, + "fleet_server_host_id": { + "nullable": true, + "type": "string" + }, + "global_data_tags": { + "description": "User defined data tags that are added to all of the inputs. The values can be strings or numbers.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "has_agent_version_conditions": { + "type": "boolean" + }, + "has_fleet_server": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "inactivity_timeout": { + "default": 1209600, + "minimum": 0, + "type": "number" + }, + "is_default": { + "type": "boolean" + }, + "is_default_fleet_server": { + "type": "boolean" + }, + "is_managed": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "is_protected": { + "description": "Indicates whether the agent policy has tamper protection enabled. Default false.", + "type": "boolean" + }, + "keep_monitoring_alive": { + "default": false, + "description": "When set to true, monitoring will be enabled but logs/metrics collection will be disabled", + "nullable": true, + "type": "boolean" + }, + "monitoring_diagnostics": { + "additionalProperties": false, + "properties": { + "limit": { + "additionalProperties": false, + "properties": { + "burst": { + "type": "number" + }, + "interval": { + "type": "string" + } + }, + "type": "object" + }, + "uploader": { + "additionalProperties": false, + "properties": { + "init_dur": { + "type": "string" + }, + "max_dur": { + "type": "string" + }, + "max_retries": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "monitoring_enabled": { + "items": { + "enum": [ + "logs", + "metrics", + "traces" + ], + "type": "string" + }, + "maxItems": 3, + "type": "array" + }, + "monitoring_http": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "port": { + "maximum": 65353, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "monitoring_output_id": { + "nullable": true, + "type": "string" + }, + "monitoring_pprof_enabled": { + "type": "boolean" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "namespace": { + "minLength": 1, + "type": "string" + }, + "overrides": { + "additionalProperties": {}, + "description": "Override settings that are defined in the agent policy. Input settings cannot be overridden. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "type": "object" + }, + "package_policies": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "description": "This field is present only when retrieving a single agent policy, or when retrieving a list of agent policies with the ?full=true parameter", + "items": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + ] + }, + "required_versions": { + "items": { + "additionalProperties": false, + "properties": { + "percentage": { + "description": "Target percentage of agents to auto upgrade", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "version": { + "description": "Target version for automatic agent upgrade", + "type": "string" + } + }, + "required": [ + "version", + "percentage" + ], + "type": "object" + }, + "maxItems": 100, + "nullable": true, + "type": "array" + }, + "revision": { + "type": "number" + }, + "schema_version": { + "type": "string" + }, + "space_ids": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "status": { + "enum": [ + "active", + "inactive" + ], + "type": "string" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the agent policy supports agentless integrations.", + "nullable": true, + "type": "boolean" + }, + "unenroll_timeout": { + "minimum": 0, + "type": "number" + }, + "unprivileged_agents": { + "type": "number" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "namespace", + "is_protected", + "status", + "updated_at", + "updated_by", + "revision" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Update an agent policy", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/agent_policies/{agentPolicyId}/auto_upgrade_agents_status": { + "get": { + "description": "Get auto upgrade agent status

[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "get-fleet-agent-policies-agentpolicyid-auto-upgrade-agents-status", + "parameters": [ + { + "in": "path", + "name": "agentPolicyId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "currentVersions": { + "items": { + "additionalProperties": false, + "properties": { + "agents": { + "description": "Number of agents that upgraded to this version", + "type": "number" + }, + "failedUpgradeActionIds": { + "description": "List of action IDs related to failed upgrades", + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "failedUpgradeAgents": { + "description": "Number of agents that failed to upgrade to this version", + "type": "number" + }, + "inProgressUpgradeActionIds": { + "description": "List of action IDs related to in-progress upgrades", + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "inProgressUpgradeAgents": { + "description": "Number of agents that are upgrading to this version", + "type": "number" + }, + "version": { + "description": "Agent version", + "type": "string" + } + }, + "required": [ + "version", + "agents", + "failedUpgradeAgents", + "inProgressUpgradeAgents" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "totalAgents": { + "type": "number" + } + }, + "required": [ + "currentVersions", + "totalAgents" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get auto upgrade agent status", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/agent_policies/{agentPolicyId}/copy": { + "post": { + "description": "Copy an agent policy by ID.

[Required authorization] Route required privileges: fleet-agent-policies-all.", + "operationId": "post-fleet-agent-policies-agentpolicyid-copy", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "agentPolicyId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "format", + "required": false, + "schema": { + "enum": [ + "simplified", + "legacy" + ], + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "name": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "advanced_settings": { + "additionalProperties": false, + "properties": { + "agent_download_target_directory": { + "nullable": true + }, + "agent_download_timeout": { + "nullable": true + }, + "agent_internal": { + "nullable": true + }, + "agent_limits_go_max_procs": { + "nullable": true + }, + "agent_logging_files_interval": { + "nullable": true + }, + "agent_logging_files_keepfiles": { + "nullable": true + }, + "agent_logging_files_rotateeverybytes": { + "nullable": true + }, + "agent_logging_level": { + "nullable": true + }, + "agent_logging_metrics_period": { + "nullable": true + }, + "agent_logging_to_files": { + "nullable": true + }, + "agent_monitoring_runtime_experimental": { + "nullable": true + } + }, + "type": "object" + }, + "agent_features": { + "items": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "enabled" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "agentless": { + "additionalProperties": false, + "properties": { + "cloud_connectors": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "target_csp": { + "enum": [ + "aws", + "azure", + "gcp" + ], + "type": "string" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "resources": { + "additionalProperties": false, + "properties": { + "requests": { + "additionalProperties": false, + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "agents": { + "type": "number" + }, + "data_output_id": { + "nullable": true, + "type": "string" + }, + "description": { + "type": "string" + }, + "download_source_id": { + "nullable": true, + "type": "string" + }, + "fips_agents": { + "type": "number" + }, + "fleet_server_host_id": { + "nullable": true, + "type": "string" + }, + "global_data_tags": { + "description": "User defined data tags that are added to all of the inputs. The values can be strings or numbers.", + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "has_agent_version_conditions": { + "type": "boolean" + }, + "has_fleet_server": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "inactivity_timeout": { + "default": 1209600, + "minimum": 0, + "type": "number" + }, + "is_default": { + "type": "boolean" + }, + "is_default_fleet_server": { + "type": "boolean" + }, + "is_managed": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "is_protected": { + "description": "Indicates whether the agent policy has tamper protection enabled. Default false.", + "type": "boolean" + }, + "keep_monitoring_alive": { + "default": false, + "description": "When set to true, monitoring will be enabled but logs/metrics collection will be disabled", + "nullable": true, + "type": "boolean" + }, + "monitoring_diagnostics": { + "additionalProperties": false, + "properties": { + "limit": { + "additionalProperties": false, + "properties": { + "burst": { + "type": "number" + }, + "interval": { + "type": "string" + } + }, + "type": "object" + }, + "uploader": { + "additionalProperties": false, + "properties": { + "init_dur": { + "type": "string" + }, + "max_dur": { + "type": "string" + }, + "max_retries": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "monitoring_enabled": { + "items": { + "enum": [ + "logs", + "metrics", + "traces" + ], + "type": "string" + }, + "maxItems": 3, + "type": "array" + }, + "monitoring_http": { + "additionalProperties": false, + "properties": { + "buffer": { + "additionalProperties": false, + "properties": { + "enabled": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "port": { + "maximum": 65353, + "minimum": 0, + "type": "number" + } + }, + "type": "object" + }, + "monitoring_output_id": { + "nullable": true, + "type": "string" + }, + "monitoring_pprof_enabled": { + "type": "boolean" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "namespace": { + "minLength": 1, + "type": "string" + }, + "overrides": { + "additionalProperties": {}, + "description": "Override settings that are defined in the agent policy. Input settings cannot be overridden. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "type": "object" + }, + "package_policies": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "description": "This field is present only when retrieving a single agent policy, or when retrieving a list of agent policies with the ?full=true parameter", + "items": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + ] + }, + "required_versions": { + "items": { + "additionalProperties": false, + "properties": { + "percentage": { + "description": "Target percentage of agents to auto upgrade", + "maximum": 100, + "minimum": 0, + "type": "number" + }, + "version": { + "description": "Target version for automatic agent upgrade", + "type": "string" + } + }, + "required": [ + "version", + "percentage" + ], + "type": "object" + }, + "maxItems": 100, + "nullable": true, + "type": "array" + }, + "revision": { + "type": "number" + }, + "schema_version": { + "type": "string" + }, + "space_ids": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "status": { + "enum": [ + "active", + "inactive" + ], + "type": "string" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the agent policy supports agentless integrations.", + "nullable": true, + "type": "boolean" + }, + "unenroll_timeout": { + "minimum": 0, + "type": "number" + }, + "unprivileged_agents": { + "type": "number" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "namespace", + "is_protected", + "status", + "updated_at", + "updated_by", + "revision" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Copy an agent policy", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/agent_policies/{agentPolicyId}/download": { + "get": { + "description": "Download an agent policy by ID.

[Required authorization] Route required privileges: fleet-agent-policies-read OR fleet-setup.", + "operationId": "get-fleet-agent-policies-agentpolicyid-download", + "parameters": [ + { + "in": "path", + "name": "agentPolicyId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "download", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "standalone", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "kubernetes", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "404": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "Not found." + } + }, + "summary": "Download an agent policy", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/agent_policies/{agentPolicyId}/full": { + "get": { + "description": "Get a full agent policy by ID.

[Required authorization] Route required privileges: fleet-agent-policies-read.", + "operationId": "get-fleet-agent-policies-agentpolicyid-full", + "parameters": [ + { + "in": "path", + "name": "agentPolicyId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "download", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "standalone", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "kubernetes", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "agent": { + "additionalProperties": false, + "properties": { + "download": { + "additionalProperties": false, + "properties": { + "proxy_headers": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + }, + { + "type": "number" + } + ] + }, + "nullable": true, + "type": "object" + }, + "proxy_url": { + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "additionalProperties": true, + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "sourceURI": { + "type": "string" + }, + "ssl": { + "additionalProperties": false, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "renegotiation": { + "type": "string" + }, + "verification_mode": { + "type": "string" + } + }, + "type": "object" + }, + "target_directory": { + "type": "string" + }, + "timeout": { + "type": "string" + } + }, + "required": [ + "sourceURI" + ], + "type": "object" + }, + "features": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "type": "object" + }, + "internal": {}, + "limits": { + "additionalProperties": false, + "properties": { + "go_max_procs": { + "type": "number" + } + }, + "type": "object" + }, + "logging": { + "additionalProperties": false, + "properties": { + "files": { + "additionalProperties": false, + "properties": { + "interval": { + "type": "string" + }, + "keepfiles": { + "type": "number" + }, + "rotateeverybytes": { + "type": "number" + } + }, + "type": "object" + }, + "level": { + "type": "string" + }, + "metrics": { + "additionalProperties": false, + "properties": { + "period": { + "type": "string" + } + }, + "type": "object" + }, + "to_files": { + "type": "boolean" + } + }, + "type": "object" + }, + "monitoring": { + "additionalProperties": false, + "properties": { + "_runtime_experimental": { + "type": "string" + }, + "apm": {}, + "diagnostics": { + "additionalProperties": false, + "properties": { + "limit": { + "additionalProperties": false, + "properties": { + "burst": { + "type": "number" + }, + "interval": { + "type": "string" + } + }, + "type": "object" + }, + "uploader": { + "additionalProperties": false, + "properties": { + "init_dur": { + "type": "string" + }, + "max_dur": { + "type": "string" + }, + "max_retries": { + "type": "number" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "http": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "port": { + "type": "number" + } + }, + "type": "object" + }, + "logs": { + "type": "boolean" + }, + "metrics": { + "type": "boolean" + }, + "namespace": { + "type": "string" + }, + "pprof": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "traces": { + "type": "boolean" + }, + "use_output": { + "type": "string" + } + }, + "required": [ + "enabled", + "metrics", + "logs", + "traces", + "apm" + ], + "type": "object" + }, + "protection": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "signing_key": { + "type": "string" + }, + "uninstall_token_hash": { + "type": "string" + } + }, + "required": [ + "enabled", + "uninstall_token_hash", + "signing_key" + ], + "type": "object" + } + }, + "required": [ + "monitoring", + "download", + "features", + "internal" + ], + "type": "object" + }, + "connectors": { + "additionalProperties": {}, + "type": "object" + }, + "exporters": { + "additionalProperties": {}, + "type": "object" + }, + "extensions": { + "additionalProperties": {}, + "type": "object" + }, + "fleet": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "proxy_headers": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + }, + { + "type": "number" + } + ] + }, + "nullable": true, + "type": "object" + }, + "proxy_url": { + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "additionalProperties": true, + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "renegotiation": { + "type": "string" + }, + "verification_mode": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "kibana": { + "additionalProperties": false, + "properties": { + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "path": { + "type": "string" + }, + "protocol": { + "type": "string" + } + }, + "required": [ + "hosts", + "protocol" + ], + "type": "object" + } + }, + "required": [ + "kibana" + ], + "type": "object" + } + ] + }, + "id": { + "type": "string" + }, + "inputs": { + "items": { + "additionalProperties": true, + "properties": { + "data_stream": { + "additionalProperties": true, + "properties": { + "namespace": { + "type": "string" + } + }, + "required": [ + "namespace" + ], + "type": "object" + }, + "id": { + "type": "string" + }, + "meta": { + "additionalProperties": true, + "properties": { + "package": { + "additionalProperties": true, + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + } + }, + "type": "object" + }, + "name": { + "type": "string" + }, + "package_policy_id": { + "type": "string" + }, + "processors": { + "items": { + "additionalProperties": true, + "properties": { + "add_fields": { + "additionalProperties": true, + "properties": { + "fields": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "object" + }, + "target": { + "type": "string" + } + }, + "required": [ + "target", + "fields" + ], + "type": "object" + } + }, + "required": [ + "add_fields" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "revision": { + "type": "number" + }, + "streams": { + "items": { + "additionalProperties": true, + "properties": { + "data_stream": { + "additionalProperties": true, + "properties": { + "dataset": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset" + ], + "type": "object" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id", + "data_stream" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "type": { + "type": "string" + }, + "use_output": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "revision", + "type", + "data_stream", + "use_output", + "package_policy_id" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "namespaces": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "output_permissions": { + "additionalProperties": { + "additionalProperties": {}, + "type": "object" + }, + "type": "object" + }, + "outputs": { + "additionalProperties": { + "additionalProperties": true, + "properties": { + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "proxy_headers": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + }, + { + "type": "number" + } + ] + }, + "nullable": true, + "type": "object" + }, + "proxy_url": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "type": "object" + }, + "processors": { + "additionalProperties": {}, + "type": "object" + }, + "receivers": { + "additionalProperties": {}, + "type": "object" + }, + "revision": { + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "service": { + "additionalProperties": false, + "properties": { + "extensions": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "pipelines": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "exporters": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "processors": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "receivers": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + } + }, + "type": "object", + "x-oas-optional": true + }, + "type": "object" + } + }, + "type": "object" + }, + "signed": { + "additionalProperties": false, + "properties": { + "data": { + "type": "string" + }, + "signature": { + "type": "string" + } + }, + "required": [ + "data", + "signature" + ], + "type": "object" + } + }, + "required": [ + "id", + "outputs", + "inputs" + ], + "type": "object" + } + ] + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get a full agent policy", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/agent_policies/{agentPolicyId}/outputs": { + "get": { + "description": "Get a list of outputs associated with agent policy by policy id.

[Required authorization] Route required privileges: fleet-agent-policies-read AND fleet-settings-read.", + "operationId": "get-fleet-agent-policies-agentpolicyid-outputs", + "parameters": [ + { + "in": "path", + "name": "agentPolicyId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "agentPolicyId": { + "type": "string" + }, + "data": { + "additionalProperties": false, + "properties": { + "integrations": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "integrationPolicyName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "pkgName": { + "type": "string" + } + }, + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "output": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + } + }, + "required": [ + "output" + ], + "type": "object" + }, + "monitoring": { + "additionalProperties": false, + "properties": { + "output": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + } + }, + "required": [ + "output" + ], + "type": "object" + } + }, + "required": [ + "monitoring", + "data" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get outputs for an agent policy", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/agent_status": { + "get": { + "operationId": "get-fleet-agent-status", + "parameters": [ + { + "in": "query", + "name": "policyId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "policyIds", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "string" + } + ] + } + }, + { + "in": "query", + "name": "kuery", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "results": { + "additionalProperties": false, + "properties": { + "active": { + "type": "number" + }, + "all": { + "type": "number" + }, + "error": { + "type": "number" + }, + "events": { + "type": "number" + }, + "inactive": { + "type": "number" + }, + "offline": { + "type": "number" + }, + "online": { + "type": "number" + }, + "orphaned": { + "type": "number" + }, + "other": { + "type": "number" + }, + "unenrolled": { + "type": "number" + }, + "uninstalled": { + "type": "number" + }, + "updating": { + "type": "number" + } + }, + "required": [ + "events", + "online", + "error", + "offline", + "other", + "updating", + "inactive", + "unenrolled", + "all", + "active" + ], + "type": "object" + } + }, + "required": [ + "results" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get an agent status summary", + "tags": [ + "Elastic Agent status" + ] + } + }, + "/api/fleet/agent_status/data": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "get-fleet-agent-status-data", + "parameters": [ + { + "in": "query", + "name": "agentsIds", + "required": true, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "type": "string" + } + ] + } + }, + { + "in": "query", + "name": "pkgName", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "pkgVersion", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "previewData", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "dataPreview": { + "items": {}, + "maxItems": 10000, + "type": "array" + }, + "items": { + "items": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "data": { + "type": "boolean" + } + }, + "required": [ + "data" + ], + "type": "object" + }, + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items", + "dataPreview" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get incoming agent data", + "tags": [ + "Elastic Agents" + ] + } + }, + "/api/fleet/agentless_policies": { + "post": { + "description": "Create an agentless policy", + "operationId": "post-fleet-agentless-policies", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The format of the response package policy.", + "in": "query", + "name": "format", + "required": false, + "schema": { + "default": "simplified", + "enum": [ + "legacy", + "simplified" + ], + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "createAgentlessPoliciesRequestExample": { + "description": "Example request to create agentless policies", + "value": { + "description": "test", + "inputs": { + "ESS Billing-cel": { + "enabled": true, + "streams": { + "ess_billing.billing": { + "enabled": true, + "vars": { + "hide_sensitive": true, + "http_client_timeout": "30s", + "lookbehind": 365, + "tags": [ + "forwarded", + "billing" + ] + } + }, + "ess_billing.credits": { + "enabled": false + } + }, + "vars": { + "api_key": "", + "organization_id": "1234" + } + } + }, + "name": "ess_billing-1", + "namespace": "default", + "package": { + "name": "ess_billing", + "version": "1.6.0" + } + } + }, + "createAgentlessPoliciesReuseAWSCloudConnectorExample": { + "description": "Example request to create agentless policy reusing an existing AWS cloud connector", + "value": { + "cloud_connector": { + "cloud_connector_id": "existing-aws-connector-id", + "target_csp": "aws" + }, + "description": "CSPM integration for AWS reusing existing cloud connector", + "inputs": { + "cspm-cloudbeat/cis_aws": { + "enabled": true, + "streams": { + "cloud_security_posture.findings": { + "enabled": true, + "vars": { + "aws.account_type": "organization-account", + "aws.credentials.type": "cloud_connector", + "aws.supports_cloud_connectors": true, + "external_id": { + "id": "ABCDEFGHIJKLMNOPQRST", + "isSecretRef": true + }, + "role_arn": "arn:aws:iam::123456789012:role/TestRole" + } + } + }, + "vars": { + "cloud_formation_template": "https://console.aws.amazon.com/cloudformation/home#/stacks/quickcreate?templateURL=https://elastic-cspm-cft.s3.eu-central-1.amazonaws.com/cloudformation-cspm-ACCOUNT_TYPE-9.2.0.yml" + } + }, + "cspm-cloudbeat/cis_azure": { + "enabled": false + }, + "cspm-cloudbeat/cis_gcp": { + "enabled": false + } + }, + "name": "cspm-aws-reuse-policy", + "namespace": "default", + "package": { + "name": "cloud_security_posture", + "version": "3.1.1" + }, + "vars": { + "deployment": "aws", + "posture": "cspm" + } + } + }, + "createAgentlessPoliciesWithAWSCloudConnectorExample": { + "description": "Example request to create agentless policy with AWS cloud connector", + "value": { + "cloud_connector": { + "target_csp": "aws" + }, + "description": "CSPM integration for AWS with cloud connector", + "inputs": { + "cspm-cloudbeat/cis_aws": { + "enabled": true, + "streams": { + "cloud_security_posture.findings": { + "enabled": true, + "vars": { + "aws.account_type": "organization-account", + "aws.credentials.type": "cloud_connector", + "aws.supports_cloud_connectors": true, + "external_id": { + "id": "ABCDEFGHIJKLMNOPQRST", + "isSecretRef": true + }, + "role_arn": "arn:aws:iam::123456789012:role/TestRole" + } + } + }, + "vars": { + "cloud_formation_template": "https://console.aws.amazon.com/cloudformation/home#/stacks/quickcreate?templateURL=https://elastic-cspm-cft.s3.eu-central-1.amazonaws.com/cloudformation-cspm-ACCOUNT_TYPE-9.2.0.yml" + } + }, + "cspm-cloudbeat/cis_azure": { + "enabled": false + }, + "cspm-cloudbeat/cis_gcp": { + "enabled": false + } + }, + "name": "cspm-aws-policy", + "namespace": "default", + "package": { + "name": "cloud_security_posture", + "version": "3.1.1" + }, + "vars": { + "deployment": "aws", + "posture": "cspm" + } + } + }, + "createAgentlessPoliciesWithAzureCloudConnectorExample": { + "description": "Example request to create agentless policy with Azure cloud connector", + "value": { + "cloud_connector": { + "target_csp": "azure" + }, + "description": "CSPM integration for Azure with cloud connector", + "inputs": { + "cspm-cloudbeat/cis_aws": { + "enabled": false + }, + "cspm-cloudbeat/cis_azure": { + "enabled": true, + "streams": { + "cloud_security_posture.findings": { + "enabled": true, + "vars": { + "azure.account_type": "organization-account", + "azure_credentials_cloud_connector_id": { + "type": "text", + "value": "existing-azure-credentials-connector-id" + }, + "client_id": { + "id": "client-secret-id", + "isSecretRef": true + }, + "tenant_id": { + "id": "tenant-secret-id", + "isSecretRef": true + } + } + } + } + }, + "cspm-cloudbeat/cis_gcp": { + "enabled": false + } + }, + "name": "cspm-azure-policy", + "namespace": "default", + "package": { + "name": "cloud_security_posture", + "version": "3.1.1" + }, + "vars": { + "deployment": "azure", + "posture": "cspm" + } + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 100, + "nullable": true, + "type": "array" + }, + "cloud_connector": { + "additionalProperties": false, + "properties": { + "cloud_connector_id": { + "description": "ID of an existing cloud connector to reuse. If not provided, a new connector will be created.", + "type": "string" + }, + "enabled": { + "default": false, + "description": "Whether cloud connectors are enabled for this policy.", + "type": "boolean" + }, + "name": { + "description": "Optional name for the cloud connector. If not provided, will be auto-generated from credentials.", + "maxLength": 255, + "minLength": 1, + "type": "string" + } + }, + "type": "object" + }, + "description": { + "description": "Policy description.", + "type": "string" + }, + "force": { + "description": "Force package policy creation even if the package is not verified, or if the agent policy is managed.", + "type": "boolean" + }, + "id": { + "description": "Policy unique identifier.", + "type": "string" + }, + "inputs": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object" + }, + "name": { + "description": "Unique name for the policy.", + "type": "string" + }, + "namespace": { + "description": "Policy namespace. When not specified, it inherits the agent policy namespace.", + "type": "string" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_template": { + "description": "The policy template to use for the agentless package policy. If not provided, the default policy template will be used.", + "type": "string" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "required": [ + "name", + "package" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "createAgentlessPoliciesResponseExample": { + "description": "Example response showing the successful result of communication initialisation over MCP protocol", + "value": { + "item": { + "created_at": "2025-11-06T18:27:43.541Z", + "created_by": "test_user", + "description": "test", + "enabled": true, + "id": "d52a7812-5736-4fdc-aed8-72152afa1ffa", + "inputs": { + "ESS Billing-cel": { + "enabled": true, + "streams": { + "ess_billing.billing": { + "enabled": true, + "vars": { + "hide_sensitive": true, + "http_client_timeout": "30s", + "lookbehind": 365, + "tags": [ + "forwarded", + "billing" + ] + } + }, + "ess_billing.credits": { + "enabled": false + } + }, + "vars": { + "api_key": { + "id": "QY1sWpoBbWcMW-edr0Ee", + "isSecretRef": true + }, + "organization_id": "1234", + "url": "https://billing.elastic-cloud.com" + } + } + }, + "name": "ess_billing-1", + "namespace": "default", + "package": { + "name": "ess_billing", + "title": "Elasticsearch Service Billing", + "version": "1.6.0" + }, + "revision": 1, + "secret_references": [ + { + "id": "QY1sWpoBbWcMW-edr0Ee" + } + ], + "supports_agentless": true, + "updated_at": "2025-11-06T18:27:43.541Z", + "updated_by": "test_user", + "version": "WzE0OTgsMV0=" + } + } + }, + "createAgentlessPoliciesWithAWSCloudConnectorResponseExample": { + "description": "Example response for AWS cloud connector integration", + "value": { + "item": { + "cloud_connector_id": "aws-connector-67890", + "created_at": "2025-11-06T18:27:43.541Z", + "created_by": "test_user", + "description": "CSPM integration for AWS with cloud connector", + "enabled": true, + "id": "aws-policy-12345", + "inputs": { + "cspm-cloudbeat/cis_aws": { + "enabled": true, + "streams": { + "cloud_security_posture.findings": { + "enabled": true, + "vars": { + "aws.account_type": "organization-account", + "aws.credentials.type": "cloud_connector", + "external_id": { + "id": "secret-external-id-123", + "isSecretRef": true + }, + "role_arn": "arn:aws:iam::123456789012:role/TestRole" + } + } + }, + "vars": { + "cloud_formation_template": "https://console.aws.amazon.com/cloudformation/home#/stacks/quickcreate?templateURL=https://elastic-cspm-cft.s3.eu-central-1.amazonaws.com/cloudformation-cspm-ACCOUNT_TYPE-9.2.0.yml" + } + }, + "cspm-cloudbeat/cis_azure": { + "enabled": false + }, + "cspm-cloudbeat/cis_gcp": { + "enabled": false + } + }, + "name": "cspm-aws-policy", + "namespace": "default", + "package": { + "name": "cloud_security_posture", + "title": "Cloud Security Posture Management", + "version": "3.1.1" + }, + "revision": 1, + "secret_references": [ + { + "id": "secret-external-id-123" + } + ], + "supports_agentless": true, + "supports_cloud_connector": true, + "updated_at": "2025-11-06T18:27:43.541Z", + "updated_by": "test_user", + "vars": { + "deployment": "aws", + "posture": "cspm" + }, + "version": "WzE0OTgsMV0=" + } + } + }, + "createAgentlessPoliciesWithAzureCloudConnectorResponseExample": { + "description": "Example response for Azure cloud connector integration", + "value": { + "item": { + "cloud_connector_id": "azure-connector-67890", + "created_at": "2025-11-06T18:27:43.541Z", + "created_by": "test_user", + "description": "CSPM integration for Azure with cloud connector", + "enabled": true, + "id": "azure-policy-12345", + "inputs": { + "cspm-cloudbeat/cis_aws": { + "enabled": false + }, + "cspm-cloudbeat/cis_azure": { + "enabled": true, + "streams": { + "cloud_security_posture.findings": { + "enabled": true, + "vars": { + "azure.account_type": "organization-account", + "azure_credentials_cloud_connector_id": { + "type": "text", + "value": "existing-azure-credentials-connector-id" + }, + "client_id": { + "id": "client-secret-id-456", + "isSecretRef": true + }, + "tenant_id": { + "id": "tenant-secret-id-123", + "isSecretRef": true + } + } + } + } + }, + "cspm-cloudbeat/cis_gcp": { + "enabled": false + } + }, + "name": "cspm-azure-policy", + "namespace": "default", + "package": { + "name": "cloud_security_posture", + "title": "Cloud Security Posture Management", + "version": "3.1.1" + }, + "revision": 1, + "secret_references": [ + { + "id": "tenant-secret-id-123" + }, + { + "id": "client-secret-id-456" + } + ], + "supports_agentless": true, + "supports_cloud_connector": true, + "updated_at": "2025-11-06T18:27:43.541Z", + "updated_by": "test_user", + "vars": { + "deployment": "azure", + "posture": "cspm" + }, + "version": "WzE0OTgsMV0=" + } + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "description": "The created agentless package policy.", + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful response" + }, + "400": { + "content": { + "application/json": { + "examples": { + "genericErrorResponseExample": { + "description": "Example of a generic error response", + "value": { + "error": "Bad Request", + "message": "An error message describing what went wrong", + "statusCode": 400 + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "Bad Request" + }, + "409": { + "content": { + "application/json": { + "examples": { + "conflictErrorResponseExample": { + "description": "Example of a conflict error response", + "value": { + "error": "Conflict", + "message": "An error message describing what went wrong", + "statusCode": 409 + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "Conflict" + } + }, + "summary": "Create an agentless policy", + "tags": [ + "Fleet agentless policies" + ], + "x-state": "Technical Preview; added in 9.3.0" + } + }, + "/api/fleet/agentless_policies/{policyId}": { + "delete": { + "description": "Delete an agentless policy", + "operationId": "delete-fleet-agentless-policies-policyid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The ID of the policy to delete.", + "in": "path", + "name": "policyId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Force delete the policy even if the policy is managed.", + "in": "query", + "name": "force", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "createAgentlessPoliciesResponseExample": { + "description": "Example response showing the successful result of communication initialisation over MCP protocol", + "value": { + "item": { + "id": "d52a7812-5736-4fdc-aed8-72152afa1ffa" + } + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Response for deleting an agentless package policy.", + "properties": { + "id": { + "description": "The ID of the deleted agentless package policy.", + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful response" + }, + "400": { + "content": { + "application/json": { + "examples": { + "genericErrorResponseExample": { + "description": "Example of a generic error response", + "value": { + "error": "Bad Request", + "message": "An error message describing what went wrong", + "statusCode": 400 + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "Bad Request" + }, + "409": { + "content": { + "application/json": { + "examples": { + "conflictErrorResponseExample": { + "description": "Example of a conflict error response", + "value": { + "error": "Conflict", + "message": "An error message describing what went wrong", + "statusCode": 409 + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "Conflict" + } + }, + "summary": "Delete an agentless policy", + "tags": [ + "Fleet agentless policies" + ], + "x-state": "Technical Preview; added in 9.3.0" + } + }, + "/api/fleet/agents": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "get-fleet-agents", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "perPage", + "required": false, + "schema": { + "default": 20, + "type": "number" + } + }, + { + "in": "query", + "name": "kuery", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "showAgentless", + "required": false, + "schema": { + "default": true, + "type": "boolean" + } + }, + { + "in": "query", + "name": "showInactive", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + }, + { + "in": "query", + "name": "withMetrics", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + }, + { + "in": "query", + "name": "showUpgradeable", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + }, + { + "in": "query", + "name": "getStatusSummary", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + }, + { + "in": "query", + "name": "sortField", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortOrder", + "required": false, + "schema": { + "enum": [ + "asc", + "desc" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "searchAfter", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "openPit", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "pitId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "pitKeepAlive", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "access_api_key": { + "type": "string" + }, + "access_api_key_id": { + "type": "string" + }, + "active": { + "type": "boolean" + }, + "agent": { + "additionalProperties": true, + "properties": { + "id": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "version" + ], + "type": "object" + }, + "audit_unenrolled_reason": { + "type": "string" + }, + "components": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "message": { + "type": "string" + }, + "status": { + "enum": [ + "STARTING", + "CONFIGURING", + "HEALTHY", + "DEGRADED", + "FAILED", + "STOPPING", + "STOPPED" + ], + "type": "string" + }, + "type": { + "type": "string" + }, + "units": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "message": { + "type": "string" + }, + "payload": { + "additionalProperties": {}, + "type": "object" + }, + "status": { + "enum": [ + "STARTING", + "CONFIGURING", + "HEALTHY", + "DEGRADED", + "FAILED", + "STOPPING", + "STOPPED" + ], + "type": "string" + }, + "type": { + "enum": [ + "input", + "output", + "" + ], + "type": "string" + } + }, + "required": [ + "id", + "type", + "status", + "message" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "id", + "type", + "status", + "message" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "default_api_key": { + "type": "string" + }, + "default_api_key_history": { + "items": { + "additionalProperties": false, + "deprecated": true, + "properties": { + "id": { + "type": "string" + }, + "retired_at": { + "type": "string" + } + }, + "required": [ + "id", + "retired_at" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "default_api_key_id": { + "type": "string" + }, + "enrolled_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "last_checkin": { + "type": "string" + }, + "last_checkin_message": { + "type": "string" + }, + "last_checkin_status": { + "enum": [ + "error", + "online", + "degraded", + "updating", + "starting" + ], + "type": "string" + }, + "last_known_status": { + "enum": [ + "offline", + "error", + "online", + "inactive", + "enrolling", + "unenrolling", + "unenrolled", + "updating", + "degraded", + "uninstalled", + "orphaned" + ], + "type": "string" + }, + "local_metadata": { + "additionalProperties": {}, + "type": "object" + }, + "metrics": { + "additionalProperties": false, + "properties": { + "cpu_avg": { + "type": "number" + }, + "memory_size_byte_avg": { + "type": "number" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "outputs": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "api_key_id": { + "type": "string" + }, + "to_retire_api_key_ids": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "retired_at": { + "type": "string" + } + }, + "required": [ + "id", + "retired_at" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "type": "object" + }, + "packages": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + "policy_id": { + "type": "string" + }, + "policy_revision": { + "nullable": true, + "type": "number" + }, + "sort": { + "items": {}, + "maxItems": 10, + "type": "array" + }, + "status": { + "enum": [ + "offline", + "error", + "online", + "inactive", + "enrolling", + "unenrolling", + "unenrolled", + "updating", + "degraded", + "uninstalled", + "orphaned" + ], + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "enum": [ + "PERMANENT", + "EPHEMERAL", + "TEMPORARY" + ], + "type": "string" + }, + "unenrolled_at": { + "type": "string" + }, + "unenrollment_started_at": { + "type": "string" + }, + "unhealthy_reason": { + "items": { + "enum": [ + "input", + "output", + "other" + ], + "type": "string" + }, + "maxItems": 3, + "nullable": true, + "type": "array" + }, + "upgrade": { + "additionalProperties": false, + "properties": { + "rollbacks": { + "items": { + "additionalProperties": false, + "properties": { + "valid_until": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "valid_until", + "version" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + }, + "upgrade_attempts": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "nullable": true, + "type": "array" + }, + "upgrade_details": { + "additionalProperties": false, + "nullable": true, + "properties": { + "action_id": { + "type": "string" + }, + "metadata": { + "additionalProperties": false, + "properties": { + "download_percent": { + "type": "number" + }, + "download_rate": { + "type": "number" + }, + "error_msg": { + "type": "string" + }, + "failed_state": { + "enum": [ + "UPG_REQUESTED", + "UPG_SCHEDULED", + "UPG_DOWNLOADING", + "UPG_EXTRACTING", + "UPG_REPLACING", + "UPG_RESTARTING", + "UPG_FAILED", + "UPG_WATCHING", + "UPG_ROLLBACK" + ], + "type": "string" + }, + "retry_error_msg": { + "type": "string" + }, + "retry_until": { + "type": "string" + }, + "scheduled_at": { + "type": "string" + } + }, + "type": "object" + }, + "state": { + "enum": [ + "UPG_REQUESTED", + "UPG_SCHEDULED", + "UPG_DOWNLOADING", + "UPG_EXTRACTING", + "UPG_REPLACING", + "UPG_RESTARTING", + "UPG_FAILED", + "UPG_WATCHING", + "UPG_ROLLBACK" + ], + "type": "string" + }, + "target_version": { + "type": "string" + } + }, + "required": [ + "target_version", + "action_id", + "state" + ], + "type": "object" + }, + "upgrade_started_at": { + "nullable": true, + "type": "string" + }, + "upgraded_at": { + "nullable": true, + "type": "string" + }, + "user_provided_metadata": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "id", + "packages", + "type", + "active", + "enrolled_at", + "local_metadata" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "nextSearchAfter": { + "type": "string" + }, + "page": { + "type": "number" + }, + "perPage": { + "type": "number" + }, + "pit": { + "type": "string" + }, + "statusSummary": { + "additionalProperties": { + "type": "number" + }, + "type": "object" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "total", + "page", + "perPage" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get agents", + "tags": [ + "Elastic Agents" + ] + }, + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "post-fleet-agents", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "actionIds": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + } + }, + "required": [ + "actionIds" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get agents by action ids", + "tags": [ + "Elastic Agents" + ] + } + }, + "/api/fleet/agents/action_status": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "get-fleet-agents-action-status", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "default": 0, + "type": "number" + } + }, + { + "in": "query", + "name": "perPage", + "required": false, + "schema": { + "default": 20, + "type": "number" + } + }, + { + "in": "query", + "name": "date", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "latest", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "errorSize", + "required": false, + "schema": { + "default": 5, + "type": "number" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + }, + "cancellationTime": { + "type": "string" + }, + "completionTime": { + "type": "string" + }, + "creationTime": { + "description": "creation time of action", + "type": "string" + }, + "expiration": { + "type": "string" + }, + "hasRolloutPeriod": { + "type": "boolean" + }, + "is_automatic": { + "type": "boolean" + }, + "latestErrors": { + "items": { + "additionalProperties": false, + "description": "latest errors that happened when the agents executed the action", + "properties": { + "agentId": { + "type": "string" + }, + "error": { + "type": "string" + }, + "hostname": { + "type": "string" + }, + "timestamp": { + "type": "string" + } + }, + "required": [ + "agentId", + "error", + "timestamp" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "nbAgentsAck": { + "description": "number of agents that acknowledged the action", + "type": "number" + }, + "nbAgentsActionCreated": { + "description": "number of agents included in action from kibana", + "type": "number" + }, + "nbAgentsActioned": { + "description": "number of agents actioned", + "type": "number" + }, + "nbAgentsFailed": { + "description": "number of agents that failed to execute the action", + "type": "number" + }, + "newPolicyId": { + "description": "new policy id (POLICY_REASSIGN action)", + "type": "string" + }, + "policyId": { + "description": "policy id (POLICY_CHANGE action)", + "type": "string" + }, + "revision": { + "description": "new policy revision (POLICY_CHANGE action)", + "type": "number" + }, + "startTime": { + "description": "start time of action (scheduled actions)", + "type": "string" + }, + "status": { + "enum": [ + "COMPLETE", + "EXPIRED", + "CANCELLED", + "FAILED", + "IN_PROGRESS", + "ROLLOUT_PASSED" + ], + "type": "string" + }, + "type": { + "enum": [ + "UPGRADE", + "UNENROLL", + "SETTINGS", + "POLICY_REASSIGN", + "CANCEL", + "FORCE_UNENROLL", + "REQUEST_DIAGNOSTICS", + "UPDATE_TAGS", + "POLICY_CHANGE", + "INPUT_ACTION", + "MIGRATE", + "PRIVILEGE_LEVEL_CHANGE" + ], + "type": "string" + }, + "version": { + "description": "agent version number (UPGRADE action)", + "type": "string" + } + }, + "required": [ + "actionId", + "nbAgentsActionCreated", + "nbAgentsAck", + "nbAgentsFailed", + "type", + "nbAgentsActioned", + "status", + "creationTime" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get an agent action status", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/actions/{actionId}/cancel": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-actions-actionid-cancel", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "actionId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "ack_data": {}, + "agents": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + "created_at": { + "type": "string" + }, + "data": {}, + "expiration": { + "type": "string" + }, + "id": { + "type": "string" + }, + "minimum_execution_duration": { + "type": "number" + }, + "namespaces": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "rollout_duration_seconds": { + "type": "number" + }, + "sent_at": { + "type": "string" + }, + "source_uri": { + "type": "string" + }, + "start_time": { + "type": "string" + }, + "total": { + "type": "number" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type", + "data", + "created_at", + "ack_data" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Cancel an agent action", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/available_versions": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "get-fleet-agents-available-versions", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get available agent versions", + "tags": [ + "Elastic Agents" + ] + } + }, + "/api/fleet/agents/bulk_migrate": { + "post": { + "description": "Bulk migrate agents to another cluster.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-bulk-migrate", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "agents": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "batchSize": { + "type": "number" + }, + "enrollment_token": { + "type": "string" + }, + "settings": { + "additionalProperties": false, + "properties": { + "ca_sha256": { + "type": "string" + }, + "certificate_authorities": { + "type": "string" + }, + "elastic_agent_cert": { + "type": "string" + }, + "elastic_agent_cert_key": { + "type": "string" + }, + "elastic_agent_cert_key_passphrase": { + "type": "string" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "insecure": { + "type": "boolean" + }, + "proxy_disabled": { + "type": "boolean" + }, + "proxy_headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "proxy_url": { + "type": "string" + }, + "staging": { + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + } + }, + "type": "object" + }, + "uri": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "agents", + "uri", + "enrollment_token" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + } + }, + "required": [ + "actionId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Migrate multiple agents", + "tags": [ + "Elastic Agents" + ] + } + }, + "/api/fleet/agents/bulk_privilege_level_change": { + "post": { + "description": "Change multiple agents' privilege level to unprivileged.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-bulk-privilege-level-change", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "bulkChangeAgentPrivilegeLevelRequest": { + "value": { + "agents": "agent", + "user_info": { + "groupname": "groupname", + "password": "password", + "username": "username" + } + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "agents": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "batchSize": { + "type": "number" + }, + "user_info": { + "additionalProperties": false, + "properties": { + "groupname": { + "type": "string" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "agents" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "successResponse": { + "value": { + "actionId": "actionId" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + } + }, + "required": [ + "actionId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "examples": { + "badRequestResponse": { + "value": { + "message": "Bad Request" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk change agent privilege level", + "tags": [ + "Elastic Agents" + ], + "x-state": "Technical Preview; added in 9.3.0" + } + }, + "/api/fleet/agents/bulk_reassign": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-bulk-reassign", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "agents": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "batchSize": { + "type": "number" + }, + "includeInactive": { + "default": false, + "type": "boolean" + }, + "policy_id": { + "type": "string" + } + }, + "required": [ + "policy_id", + "agents" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + } + }, + "required": [ + "actionId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk reassign agents", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/bulk_request_diagnostics": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "post-fleet-agents-bulk-request-diagnostics", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "additional_metrics": { + "items": { + "enum": [ + "CPU" + ], + "type": "string" + }, + "maxItems": 1, + "type": "array" + }, + "agents": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "batchSize": { + "type": "number" + } + }, + "required": [ + "agents" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + } + }, + "required": [ + "actionId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk request diagnostics from agents", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/bulk_rollback": { + "post": { + "description": "Rollback multiple agents to the previous version.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-bulk-rollback", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "bulkRollbackAgentsRequest": { + "value": { + "agents": [ + "agent-1", + "agent-2" + ], + "batchSize": 100, + "includeInactive": false + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "agents": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "batchSize": { + "type": "number" + }, + "includeInactive": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "agents" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "successResponse": { + "value": { + "actionIds": [ + "actionId1", + "actionId2" + ] + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "actionIds": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "actionIds" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "examples": { + "badRequestResponse": { + "value": { + "message": "Bad Request" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk rollback agents", + "tags": [ + "Elastic Agent actions" + ], + "x-state": "Technical Preview; added in 9.4.0" + } + }, + "/api/fleet/agents/bulk_unenroll": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-bulk-unenroll", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "agents": { + "anyOf": [ + { + "items": { + "description": "list of agent IDs", + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "description": "KQL query string, leave empty to action all agents", + "type": "string" + } + ] + }, + "batchSize": { + "type": "number" + }, + "force": { + "description": "Unenrolls hosted agents too", + "type": "boolean" + }, + "includeInactive": { + "description": "When passing agents by KQL query, unenrolls inactive agents too", + "type": "boolean" + }, + "revoke": { + "description": "Revokes API keys of agents", + "type": "boolean" + } + }, + "required": [ + "agents" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + } + }, + "required": [ + "actionId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk unenroll agents", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/bulk_update_agent_tags": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-bulk-update-agent-tags", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "agents": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "batchSize": { + "type": "number" + }, + "includeInactive": { + "default": false, + "type": "boolean" + }, + "tagsToAdd": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "tagsToRemove": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + } + }, + "required": [ + "agents" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + } + }, + "required": [ + "actionId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk update agent tags", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/bulk_upgrade": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-bulk-upgrade", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "agents": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + { + "type": "string" + } + ] + }, + "batchSize": { + "type": "number" + }, + "force": { + "type": "boolean" + }, + "includeInactive": { + "default": false, + "type": "boolean" + }, + "rollout_duration_seconds": { + "minimum": 600, + "type": "number" + }, + "skipRateLimitCheck": { + "type": "boolean" + }, + "source_uri": { + "type": "string" + }, + "start_time": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "agents", + "version" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + } + }, + "required": [ + "actionId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk upgrade agents", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/files/{fileId}": { + "delete": { + "description": "Delete a file uploaded by an agent.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "delete-fleet-agents-files-fileid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "fileId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "deleted": { + "type": "boolean" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id", + "deleted" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Delete an uploaded file", + "tags": [ + "Elastic Agents" + ] + } + }, + "/api/fleet/agents/files/{fileId}/{fileName}": { + "get": { + "description": "Get a file uploaded by an agent.

[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "get-fleet-agents-files-fileid-filename", + "parameters": [ + { + "in": "path", + "name": "fileId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "fileName", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get an uploaded file", + "tags": [ + "Elastic Agents" + ] + } + }, + "/api/fleet/agents/setup": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agents-read OR fleet-agent-policies-read OR fleet-settings-read OR fleet-setup.", + "operationId": "get-fleet-agents-setup", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "A summary of the agent setup status. `isReady` indicates whether the setup is ready. If the setup is not ready, `missing_requirements` lists which requirements are missing.", + "properties": { + "isReady": { + "type": "boolean" + }, + "is_action_secrets_storage_enabled": { + "type": "boolean" + }, + "is_secrets_storage_enabled": { + "type": "boolean" + }, + "is_space_awareness_enabled": { + "type": "boolean" + }, + "is_ssl_secrets_storage_enabled": { + "type": "boolean" + }, + "missing_optional_features": { + "items": { + "enum": [ + "encrypted_saved_object_encryption_key_required" + ], + "type": "string" + }, + "maxItems": 1, + "type": "array" + }, + "missing_requirements": { + "items": { + "enum": [ + "security_required", + "tls_required", + "api_keys", + "fleet_admin_user", + "fleet_server" + ], + "type": "string" + }, + "maxItems": 5, + "type": "array" + }, + "package_verification_key_id": { + "type": "string" + } + }, + "required": [ + "isReady", + "missing_requirements", + "missing_optional_features" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get agent setup info", + "tags": [ + "Elastic Agents" + ] + }, + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-read OR fleet-agent-policies-read OR fleet-settings-read OR fleet-setup.", + "operationId": "post-fleet-agents-setup", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "A summary of the result of Fleet's `setup` lifecycle. If `isInitialized` is true, Fleet is ready to accept agent enrollment. `nonFatalErrors` may include useful insight into non-blocking issues with Fleet setup.", + "properties": { + "isInitialized": { + "type": "boolean" + }, + "nonFatalErrors": { + "items": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "message" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "isInitialized", + "nonFatalErrors" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Initiate agent setup", + "tags": [ + "Elastic Agents" + ] + } + }, + "/api/fleet/agents/tags": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "get-fleet-agents-tags", + "parameters": [ + { + "in": "query", + "name": "kuery", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "showInactive", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get agent tags", + "tags": [ + "Elastic Agents" + ] + } + }, + "/api/fleet/agents/{agentId}": { + "delete": { + "description": "Delete an agent by ID.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "delete-fleet-agents-agentid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "action": { + "enum": [ + "deleted" + ], + "type": "string" + } + }, + "required": [ + "action" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Delete an agent", + "tags": [ + "Elastic Agents" + ] + }, + "get": { + "description": "Get an agent by ID.

[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "get-fleet-agents-agentid", + "parameters": [ + { + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "withMetrics", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "access_api_key": { + "type": "string" + }, + "access_api_key_id": { + "type": "string" + }, + "active": { + "type": "boolean" + }, + "agent": { + "additionalProperties": true, + "properties": { + "id": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "version" + ], + "type": "object" + }, + "audit_unenrolled_reason": { + "type": "string" + }, + "components": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "message": { + "type": "string" + }, + "status": { + "enum": [ + "STARTING", + "CONFIGURING", + "HEALTHY", + "DEGRADED", + "FAILED", + "STOPPING", + "STOPPED" + ], + "type": "string" + }, + "type": { + "type": "string" + }, + "units": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "message": { + "type": "string" + }, + "payload": { + "additionalProperties": {}, + "type": "object" + }, + "status": { + "enum": [ + "STARTING", + "CONFIGURING", + "HEALTHY", + "DEGRADED", + "FAILED", + "STOPPING", + "STOPPED" + ], + "type": "string" + }, + "type": { + "enum": [ + "input", + "output", + "" + ], + "type": "string" + } + }, + "required": [ + "id", + "type", + "status", + "message" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "id", + "type", + "status", + "message" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "default_api_key": { + "type": "string" + }, + "default_api_key_history": { + "items": { + "additionalProperties": false, + "deprecated": true, + "properties": { + "id": { + "type": "string" + }, + "retired_at": { + "type": "string" + } + }, + "required": [ + "id", + "retired_at" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "default_api_key_id": { + "type": "string" + }, + "enrolled_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "last_checkin": { + "type": "string" + }, + "last_checkin_message": { + "type": "string" + }, + "last_checkin_status": { + "enum": [ + "error", + "online", + "degraded", + "updating", + "starting" + ], + "type": "string" + }, + "last_known_status": { + "enum": [ + "offline", + "error", + "online", + "inactive", + "enrolling", + "unenrolling", + "unenrolled", + "updating", + "degraded", + "uninstalled", + "orphaned" + ], + "type": "string" + }, + "local_metadata": { + "additionalProperties": {}, + "type": "object" + }, + "metrics": { + "additionalProperties": false, + "properties": { + "cpu_avg": { + "type": "number" + }, + "memory_size_byte_avg": { + "type": "number" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "outputs": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "api_key_id": { + "type": "string" + }, + "to_retire_api_key_ids": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "retired_at": { + "type": "string" + } + }, + "required": [ + "id", + "retired_at" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "type": "object" + }, + "packages": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + "policy_id": { + "type": "string" + }, + "policy_revision": { + "nullable": true, + "type": "number" + }, + "sort": { + "items": {}, + "maxItems": 10, + "type": "array" + }, + "status": { + "enum": [ + "offline", + "error", + "online", + "inactive", + "enrolling", + "unenrolling", + "unenrolled", + "updating", + "degraded", + "uninstalled", + "orphaned" + ], + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "enum": [ + "PERMANENT", + "EPHEMERAL", + "TEMPORARY" + ], + "type": "string" + }, + "unenrolled_at": { + "type": "string" + }, + "unenrollment_started_at": { + "type": "string" + }, + "unhealthy_reason": { + "items": { + "enum": [ + "input", + "output", + "other" + ], + "type": "string" + }, + "maxItems": 3, + "nullable": true, + "type": "array" + }, + "upgrade": { + "additionalProperties": false, + "properties": { + "rollbacks": { + "items": { + "additionalProperties": false, + "properties": { + "valid_until": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "valid_until", + "version" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + }, + "upgrade_attempts": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "nullable": true, + "type": "array" + }, + "upgrade_details": { + "additionalProperties": false, + "nullable": true, + "properties": { + "action_id": { + "type": "string" + }, + "metadata": { + "additionalProperties": false, + "properties": { + "download_percent": { + "type": "number" + }, + "download_rate": { + "type": "number" + }, + "error_msg": { + "type": "string" + }, + "failed_state": { + "enum": [ + "UPG_REQUESTED", + "UPG_SCHEDULED", + "UPG_DOWNLOADING", + "UPG_EXTRACTING", + "UPG_REPLACING", + "UPG_RESTARTING", + "UPG_FAILED", + "UPG_WATCHING", + "UPG_ROLLBACK" + ], + "type": "string" + }, + "retry_error_msg": { + "type": "string" + }, + "retry_until": { + "type": "string" + }, + "scheduled_at": { + "type": "string" + } + }, + "type": "object" + }, + "state": { + "enum": [ + "UPG_REQUESTED", + "UPG_SCHEDULED", + "UPG_DOWNLOADING", + "UPG_EXTRACTING", + "UPG_REPLACING", + "UPG_RESTARTING", + "UPG_FAILED", + "UPG_WATCHING", + "UPG_ROLLBACK" + ], + "type": "string" + }, + "target_version": { + "type": "string" + } + }, + "required": [ + "target_version", + "action_id", + "state" + ], + "type": "object" + }, + "upgrade_started_at": { + "nullable": true, + "type": "string" + }, + "upgraded_at": { + "nullable": true, + "type": "string" + }, + "user_provided_metadata": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "id", + "packages", + "type", + "active", + "enrolled_at", + "local_metadata" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get an agent", + "tags": [ + "Elastic Agents" + ] + }, + "put": { + "description": "Update an agent by ID.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "put-fleet-agents-agentid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "tags": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "user_provided_metadata": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "access_api_key": { + "type": "string" + }, + "access_api_key_id": { + "type": "string" + }, + "active": { + "type": "boolean" + }, + "agent": { + "additionalProperties": true, + "properties": { + "id": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "version" + ], + "type": "object" + }, + "audit_unenrolled_reason": { + "type": "string" + }, + "components": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "message": { + "type": "string" + }, + "status": { + "enum": [ + "STARTING", + "CONFIGURING", + "HEALTHY", + "DEGRADED", + "FAILED", + "STOPPING", + "STOPPED" + ], + "type": "string" + }, + "type": { + "type": "string" + }, + "units": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "message": { + "type": "string" + }, + "payload": { + "additionalProperties": {}, + "type": "object" + }, + "status": { + "enum": [ + "STARTING", + "CONFIGURING", + "HEALTHY", + "DEGRADED", + "FAILED", + "STOPPING", + "STOPPED" + ], + "type": "string" + }, + "type": { + "enum": [ + "input", + "output", + "" + ], + "type": "string" + } + }, + "required": [ + "id", + "type", + "status", + "message" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "id", + "type", + "status", + "message" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "default_api_key": { + "type": "string" + }, + "default_api_key_history": { + "items": { + "additionalProperties": false, + "deprecated": true, + "properties": { + "id": { + "type": "string" + }, + "retired_at": { + "type": "string" + } + }, + "required": [ + "id", + "retired_at" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "default_api_key_id": { + "type": "string" + }, + "enrolled_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "last_checkin": { + "type": "string" + }, + "last_checkin_message": { + "type": "string" + }, + "last_checkin_status": { + "enum": [ + "error", + "online", + "degraded", + "updating", + "starting" + ], + "type": "string" + }, + "last_known_status": { + "enum": [ + "offline", + "error", + "online", + "inactive", + "enrolling", + "unenrolling", + "unenrolled", + "updating", + "degraded", + "uninstalled", + "orphaned" + ], + "type": "string" + }, + "local_metadata": { + "additionalProperties": {}, + "type": "object" + }, + "metrics": { + "additionalProperties": false, + "properties": { + "cpu_avg": { + "type": "number" + }, + "memory_size_byte_avg": { + "type": "number" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "outputs": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "api_key_id": { + "type": "string" + }, + "to_retire_api_key_ids": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "retired_at": { + "type": "string" + } + }, + "required": [ + "id", + "retired_at" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "type": "object" + }, + "packages": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + "policy_id": { + "type": "string" + }, + "policy_revision": { + "nullable": true, + "type": "number" + }, + "sort": { + "items": {}, + "maxItems": 10, + "type": "array" + }, + "status": { + "enum": [ + "offline", + "error", + "online", + "inactive", + "enrolling", + "unenrolling", + "unenrolled", + "updating", + "degraded", + "uninstalled", + "orphaned" + ], + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "enum": [ + "PERMANENT", + "EPHEMERAL", + "TEMPORARY" + ], + "type": "string" + }, + "unenrolled_at": { + "type": "string" + }, + "unenrollment_started_at": { + "type": "string" + }, + "unhealthy_reason": { + "items": { + "enum": [ + "input", + "output", + "other" + ], + "type": "string" + }, + "maxItems": 3, + "nullable": true, + "type": "array" + }, + "upgrade": { + "additionalProperties": false, + "properties": { + "rollbacks": { + "items": { + "additionalProperties": false, + "properties": { + "valid_until": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "valid_until", + "version" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + }, + "upgrade_attempts": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "nullable": true, + "type": "array" + }, + "upgrade_details": { + "additionalProperties": false, + "nullable": true, + "properties": { + "action_id": { + "type": "string" + }, + "metadata": { + "additionalProperties": false, + "properties": { + "download_percent": { + "type": "number" + }, + "download_rate": { + "type": "number" + }, + "error_msg": { + "type": "string" + }, + "failed_state": { + "enum": [ + "UPG_REQUESTED", + "UPG_SCHEDULED", + "UPG_DOWNLOADING", + "UPG_EXTRACTING", + "UPG_REPLACING", + "UPG_RESTARTING", + "UPG_FAILED", + "UPG_WATCHING", + "UPG_ROLLBACK" + ], + "type": "string" + }, + "retry_error_msg": { + "type": "string" + }, + "retry_until": { + "type": "string" + }, + "scheduled_at": { + "type": "string" + } + }, + "type": "object" + }, + "state": { + "enum": [ + "UPG_REQUESTED", + "UPG_SCHEDULED", + "UPG_DOWNLOADING", + "UPG_EXTRACTING", + "UPG_REPLACING", + "UPG_RESTARTING", + "UPG_FAILED", + "UPG_WATCHING", + "UPG_ROLLBACK" + ], + "type": "string" + }, + "target_version": { + "type": "string" + } + }, + "required": [ + "target_version", + "action_id", + "state" + ], + "type": "object" + }, + "upgrade_started_at": { + "nullable": true, + "type": "string" + }, + "upgraded_at": { + "nullable": true, + "type": "string" + }, + "user_provided_metadata": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "id", + "packages", + "type", + "active", + "enrolled_at", + "local_metadata" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Update an agent by ID", + "tags": [ + "Elastic Agents" + ] + } + }, + "/api/fleet/agents/{agentId}/actions": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-agentid-actions", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "action": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "ack_data": {}, + "data": {}, + "type": { + "enum": [ + "UNENROLL", + "UPGRADE", + "POLICY_REASSIGN" + ], + "type": "string" + } + }, + "required": [ + "type", + "data", + "ack_data" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "data": { + "additionalProperties": false, + "properties": { + "log_level": { + "enum": [ + "debug", + "info", + "warning", + "error" + ], + "nullable": true, + "type": "string" + } + }, + "required": [ + "log_level" + ], + "type": "object" + }, + "type": { + "enum": [ + "SETTINGS" + ], + "type": "string" + } + }, + "required": [ + "type", + "data" + ], + "type": "object" + } + ] + } + }, + "required": [ + "action" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "ack_data": {}, + "agents": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + "created_at": { + "type": "string" + }, + "data": {}, + "expiration": { + "type": "string" + }, + "id": { + "type": "string" + }, + "minimum_execution_duration": { + "type": "number" + }, + "namespaces": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "rollout_duration_seconds": { + "type": "number" + }, + "sent_at": { + "type": "string" + }, + "source_uri": { + "type": "string" + }, + "start_time": { + "type": "string" + }, + "total": { + "type": "number" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type", + "data", + "created_at", + "ack_data" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Create an agent action", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/{agentId}/migrate": { + "post": { + "description": "Migrate a single agent to another cluster.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-agentid-migrate", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "enrollment_token": { + "type": "string" + }, + "settings": { + "additionalProperties": false, + "properties": { + "ca_sha256": { + "type": "string" + }, + "certificate_authorities": { + "type": "string" + }, + "elastic_agent_cert": { + "type": "string" + }, + "elastic_agent_cert_key": { + "type": "string" + }, + "elastic_agent_cert_key_passphrase": { + "type": "string" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "insecure": { + "type": "boolean" + }, + "proxy_disabled": { + "type": "boolean" + }, + "proxy_headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "proxy_url": { + "type": "string" + }, + "replace_token": { + "type": "string" + }, + "staging": { + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + } + }, + "type": "object" + }, + "uri": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "uri", + "enrollment_token" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + } + }, + "required": [ + "actionId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Migrate a single agent", + "tags": [ + "Elastic Agents" + ] + } + }, + "/api/fleet/agents/{agentId}/privilege_level_change": { + "post": { + "description": "Change the privilege level of a single agent to unprivileged.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-agentid-privilege-level-change", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The agent ID to change privilege level for", + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "changeAgentPrivilegeLevelRequest": { + "value": { + "user_info": { + "groupname": "groupname", + "password": "password", + "username": "username" + } + } + } + }, + "schema": { + "additionalProperties": false, + "nullable": true, + "properties": { + "user_info": { + "additionalProperties": false, + "properties": { + "groupname": { + "type": "string" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "successResponse": { + "value": { + "actionId": "actionId" + } + } + }, + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + } + }, + "required": [ + "actionId" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + ] + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "examples": { + "badRequestResponse": { + "value": { + "message": "Bad Request" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Change agent privilege level", + "tags": [ + "Elastic Agents" + ], + "x-state": "Technical Preview; added in 9.3.0" + } + }, + "/api/fleet/agents/{agentId}/reassign": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-agentid-reassign", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "policy_id": { + "type": "string" + } + }, + "required": [ + "policy_id" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Reassign an agent", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/{agentId}/request_diagnostics": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "post-fleet-agents-agentid-request-diagnostics", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "nullable": true, + "properties": { + "additional_metrics": { + "items": { + "enum": [ + "CPU" + ], + "type": "string" + }, + "maxItems": 1, + "type": "array" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + } + }, + "required": [ + "actionId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Request agent diagnostics", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/{agentId}/rollback": { + "post": { + "description": "Rollback an agent to the previous version.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-agentid-rollback", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The agent ID to rollback", + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "successResponse": { + "value": { + "actionId": "actionId" + } + } + }, + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + } + }, + "required": [ + "actionId" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + ] + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "examples": { + "badRequestResponse": { + "value": { + "message": "Bad Request" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Rollback an agent", + "tags": [ + "Elastic Agent actions" + ], + "x-state": "Technical Preview; added in 9.4.0" + } + }, + "/api/fleet/agents/{agentId}/unenroll": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-agentid-unenroll", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "nullable": true, + "properties": { + "force": { + "type": "boolean" + }, + "revoke": { + "type": "boolean" + } + }, + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Unenroll an agent", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/{agentId}/upgrade": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-agents-agentid-upgrade", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "force": { + "type": "boolean" + }, + "skipRateLimitCheck": { + "type": "boolean" + }, + "source_uri": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "version" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Upgrade an agent", + "tags": [ + "Elastic Agent actions" + ] + } + }, + "/api/fleet/agents/{agentId}/uploads": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agents-read.", + "operationId": "get-fleet-agents-agentid-uploads", + "parameters": [ + { + "in": "path", + "name": "agentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "actionId": { + "type": "string" + }, + "createTime": { + "type": "string" + }, + "error": { + "type": "string" + }, + "filePath": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "enum": [ + "READY", + "AWAITING_UPLOAD", + "DELETED", + "EXPIRED", + "IN_PROGRESS", + "FAILED" + ], + "type": "string" + } + }, + "required": [ + "id", + "name", + "filePath", + "createTime", + "status", + "actionId" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get agent uploads", + "tags": [ + "Elastic Agents" + ] + } + }, + "/api/fleet/check-permissions": { + "get": { + "operationId": "get-fleet-check-permissions", + "parameters": [ + { + "in": "query", + "name": "fleetServerSetup", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "error": { + "enum": [ + "MISSING_SECURITY", + "MISSING_PRIVILEGES", + "MISSING_FLEET_SERVER_SETUP_PRIVILEGES" + ], + "type": "string" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Check permissions", + "tags": [ + "Fleet internals" + ] + } + }, + "/api/fleet/cloud_connectors": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-read OR integrations-read.", + "operationId": "get-fleet-cloud-connectors", + "parameters": [ + { + "description": "The page number for pagination.", + "in": "query", + "name": "page", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "The number of items per page.", + "in": "query", + "name": "perPage", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "KQL query to filter cloud connectors.", + "in": "query", + "name": "kuery", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "accountType": { + "type": "string" + }, + "cloudProvider": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "packagePolicyCount": { + "type": "number" + }, + "updated_at": { + "type": "string" + }, + "vars": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "id", + "name", + "cloudProvider", + "vars", + "packagePolicyCount", + "created_at", + "updated_at" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get cloud connectors", + "tags": [ + "Fleet cloud connectors" + ], + "x-state": "Technical Preview; added in 9.2.0" + }, + "post": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-all OR integrations-all.", + "operationId": "post-fleet-cloud-connectors", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "accountType": { + "description": "The account type: single-account (single account/subscription) or organization-account (organization-wide).", + "enum": [ + "single-account", + "organization-account" + ], + "type": "string" + }, + "cloudProvider": { + "description": "The cloud provider type: aws, azure, or gcp.", + "enum": [ + "aws", + "azure", + "gcp" + ], + "type": "string" + }, + "name": { + "description": "The name of the cloud connector.", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "maxLength": 1000, + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "maxLength": 50, + "type": "string" + }, + "value": { + "anyOf": [ + { + "maxLength": 1000, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "maxLength": 255, + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "isSecretRef", + "id" + ], + "type": "object" + } + ] + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + } + ] + }, + "type": "object" + } + }, + "required": [ + "name", + "cloudProvider", + "vars" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "accountType": { + "type": "string" + }, + "cloudProvider": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "packagePolicyCount": { + "type": "number" + }, + "updated_at": { + "type": "string" + }, + "vars": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "id", + "name", + "cloudProvider", + "vars", + "packagePolicyCount", + "created_at", + "updated_at" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Create cloud connector", + "tags": [ + "Fleet cloud connectors" + ], + "x-state": "Technical Preview; added in 9.2.0" + } + }, + "/api/fleet/cloud_connectors/{cloudConnectorId}": { + "delete": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-all OR integrations-all.", + "operationId": "delete-fleet-cloud-connectors-cloudconnectorid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the cloud connector to delete.", + "in": "path", + "name": "cloudConnectorId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "If true, forces deletion even if the cloud connector is in use.", + "in": "query", + "name": "force", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Delete cloud connector (supports force deletion)", + "tags": [ + "Fleet cloud connectors" + ], + "x-state": "Technical Preview; added in 9.2.0" + }, + "get": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-read OR integrations-read.", + "operationId": "get-fleet-cloud-connectors-cloudconnectorid", + "parameters": [ + { + "description": "The unique identifier of the cloud connector.", + "in": "path", + "name": "cloudConnectorId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "accountType": { + "type": "string" + }, + "cloudProvider": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "packagePolicyCount": { + "type": "number" + }, + "updated_at": { + "type": "string" + }, + "vars": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "id", + "name", + "cloudProvider", + "vars", + "packagePolicyCount", + "created_at", + "updated_at" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get cloud connector", + "tags": [ + "Fleet cloud connectors" + ], + "x-state": "Technical Preview; added in 9.2.0" + }, + "put": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-all OR integrations-all.", + "operationId": "put-fleet-cloud-connectors-cloudconnectorid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The unique identifier of the cloud connector to update.", + "in": "path", + "name": "cloudConnectorId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "accountType": { + "description": "The account type: single-account (single account/subscription) or organization-account (organization-wide).", + "enum": [ + "single-account", + "organization-account" + ], + "type": "string" + }, + "name": { + "description": "The name of the cloud connector.", + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "maxLength": 1000, + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "maxLength": 50, + "type": "string" + }, + "value": { + "anyOf": [ + { + "maxLength": 1000, + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "maxLength": 255, + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "isSecretRef", + "id" + ], + "type": "object" + } + ] + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + } + ] + }, + "type": "object" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "accountType": { + "type": "string" + }, + "cloudProvider": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "packagePolicyCount": { + "type": "number" + }, + "updated_at": { + "type": "string" + }, + "vars": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "id", + "name", + "cloudProvider", + "vars", + "packagePolicyCount", + "created_at", + "updated_at" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Update cloud connector", + "tags": [ + "Fleet cloud connectors" + ], + "x-state": "Technical Preview; added in 9.2.0" + } + }, + "/api/fleet/cloud_connectors/{cloudConnectorId}/usage": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-read OR integrations-read.", + "operationId": "get-fleet-cloud-connectors-cloudconnectorid-usage", + "parameters": [ + { + "description": "The unique identifier of the cloud connector.", + "in": "path", + "name": "cloudConnectorId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "The page number for pagination.", + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "number" + } + }, + { + "description": "The number of items per page.", + "in": "query", + "name": "perPage", + "required": false, + "schema": { + "minimum": 1, + "type": "number" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "getCloudConnectorUsageResponseExample": { + "description": "Example response showing package policies using the cloud connector", + "value": { + "items": [ + { + "created_at": "2025-01-16T09:00:00.000Z", + "id": "package-policy-1", + "name": "CSPM AWS Policy", + "package": { + "name": "cloud_security_posture", + "title": "Cloud Security Posture Management", + "version": "3.1.1" + }, + "policy_ids": [ + "policy-id-123", + "policy-id-456" + ], + "updated_at": "2025-01-16T09:00:00.000Z" + } + ], + "page": 1, + "perPage": 20, + "total": 2 + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "package": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "title": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "title", + "version" + ], + "type": "object" + }, + "policy_ids": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + "updated_at": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "policy_ids", + "created_at", + "updated_at" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "page": { + "type": "number" + }, + "perPage": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "total", + "page", + "perPage" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "examples": { + "genericErrorResponseExample": { + "description": "Example of a generic error response", + "value": { + "error": "Bad Request", + "message": "Cloud connector not found", + "statusCode": 400 + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get cloud connector usage (package policies using the connector)", + "tags": [ + "Fleet cloud connectors" + ], + "x-state": "Technical Preview; added in 9.2.0" + } + }, + "/api/fleet/data_streams": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agents-all AND fleet-agent-policies-all AND fleet-settings-all.", + "operationId": "get-fleet-data-streams", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "data_streams": { + "items": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "id", + "title" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "dataset": { + "type": "string" + }, + "index": { + "type": "string" + }, + "last_activity_ms": { + "type": "number" + }, + "namespace": { + "type": "string" + }, + "package": { + "type": "string" + }, + "package_version": { + "type": "string" + }, + "serviceDetails": { + "additionalProperties": false, + "nullable": true, + "properties": { + "environment": { + "type": "string" + }, + "serviceName": { + "type": "string" + } + }, + "required": [ + "environment", + "serviceName" + ], + "type": "object" + }, + "size_in_bytes": { + "type": "number" + }, + "size_in_bytes_formatted": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "type": { + "type": "string" + } + }, + "required": [ + "index", + "dataset", + "namespace", + "type", + "package", + "package_version", + "last_activity_ms", + "size_in_bytes", + "size_in_bytes_formatted", + "dashboards", + "serviceDetails" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "data_streams" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get data streams", + "tags": [ + "Data streams" + ] + } + }, + "/api/fleet/enrollment_api_keys": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agents-all OR fleet-setup.", + "operationId": "get-fleet-enrollment-api-keys", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "default": 1, + "type": "number" + } + }, + { + "in": "query", + "name": "perPage", + "required": false, + "schema": { + "default": 20, + "type": "number" + } + }, + { + "in": "query", + "name": "kuery", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "active": { + "description": "When false, the enrollment API key is revoked and cannot be used for enrolling Elastic Agents.", + "type": "boolean" + }, + "api_key": { + "description": "The enrollment API key (token) used for enrolling Elastic Agents.", + "type": "string" + }, + "api_key_id": { + "description": "The ID of the API key in the Security API.", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "name": { + "description": "The name of the enrollment API key.", + "type": "string" + }, + "policy_id": { + "description": "The ID of the agent policy the Elastic Agent will be enrolled in.", + "type": "string" + } + }, + "required": [ + "id", + "api_key_id", + "api_key", + "active", + "created_at" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "list": { + "deprecated": true, + "items": { + "additionalProperties": false, + "properties": { + "active": { + "description": "When false, the enrollment API key is revoked and cannot be used for enrolling Elastic Agents.", + "type": "boolean" + }, + "api_key": { + "description": "The enrollment API key (token) used for enrolling Elastic Agents.", + "type": "string" + }, + "api_key_id": { + "description": "The ID of the API key in the Security API.", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "name": { + "description": "The name of the enrollment API key.", + "type": "string" + }, + "policy_id": { + "description": "The ID of the agent policy the Elastic Agent will be enrolled in.", + "type": "string" + } + }, + "required": [ + "id", + "api_key_id", + "api_key", + "active", + "created_at" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "page": { + "type": "number" + }, + "perPage": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "total", + "page", + "perPage", + "list" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get enrollment API keys", + "tags": [ + "Fleet enrollment API keys" + ] + }, + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-enrollment-api-keys", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "expiration": { + "type": "string" + }, + "name": { + "type": "string" + }, + "policy_id": { + "type": "string" + } + }, + "required": [ + "policy_id" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "action": { + "enum": [ + "created" + ], + "type": "string" + }, + "item": { + "additionalProperties": false, + "properties": { + "active": { + "description": "When false, the enrollment API key is revoked and cannot be used for enrolling Elastic Agents.", + "type": "boolean" + }, + "api_key": { + "description": "The enrollment API key (token) used for enrolling Elastic Agents.", + "type": "string" + }, + "api_key_id": { + "description": "The ID of the API key in the Security API.", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "name": { + "description": "The name of the enrollment API key.", + "type": "string" + }, + "policy_id": { + "description": "The ID of the agent policy the Elastic Agent will be enrolled in.", + "type": "string" + } + }, + "required": [ + "id", + "api_key_id", + "api_key", + "active", + "created_at" + ], + "type": "object" + } + }, + "required": [ + "item", + "action" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Create an enrollment API key", + "tags": [ + "Fleet enrollment API keys" + ] + } + }, + "/api/fleet/enrollment_api_keys/{keyId}": { + "delete": { + "description": "Revoke an enrollment API key by ID by marking it as inactive.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "delete-fleet-enrollment-api-keys-keyid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "keyId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "action": { + "enum": [ + "deleted" + ], + "type": "string" + } + }, + "required": [ + "action" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Revoke an enrollment API key", + "tags": [ + "Fleet enrollment API keys" + ] + }, + "get": { + "description": "Get an enrollment API key by ID.

[Required authorization] Route required privileges: fleet-agents-all OR fleet-setup.", + "operationId": "get-fleet-enrollment-api-keys-keyid", + "parameters": [ + { + "in": "path", + "name": "keyId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "active": { + "description": "When false, the enrollment API key is revoked and cannot be used for enrolling Elastic Agents.", + "type": "boolean" + }, + "api_key": { + "description": "The enrollment API key (token) used for enrolling Elastic Agents.", + "type": "string" + }, + "api_key_id": { + "description": "The ID of the API key in the Security API.", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "name": { + "description": "The name of the enrollment API key.", + "type": "string" + }, + "policy_id": { + "description": "The ID of the agent policy the Elastic Agent will be enrolled in.", + "type": "string" + } + }, + "required": [ + "id", + "api_key_id", + "api_key", + "active", + "created_at" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get an enrollment API key", + "tags": [ + "Fleet enrollment API keys" + ] + } + }, + "/api/fleet/epm/bulk_assets": { + "post": { + "description": "[Required authorization] Route required privileges: integrations-read OR fleet-setup OR fleet-all.", + "operationId": "post-fleet-epm-bulk-assets", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "assetIds": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + } + }, + "required": [ + "assetIds" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "appLink": { + "type": "string" + }, + "attributes": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "service": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": [ + "id", + "type", + "attributes" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk get assets", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/categories": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-read OR fleet-setup OR fleet-all.", + "operationId": "get-fleet-epm-categories", + "parameters": [ + { + "in": "query", + "name": "prerelease", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "include_policy_templates", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "count": { + "type": "number" + }, + "id": { + "type": "string" + }, + "parent_id": { + "type": "string" + }, + "parent_title": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "id", + "title", + "count" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get package categories", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/custom_integrations": { + "post": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "post-fleet-epm-custom-integrations", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "datasets": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": [ + "logs", + "metrics", + "traces", + "synthetics", + "profiling" + ], + "type": "string" + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "force": { + "type": "boolean" + }, + "integrationName": { + "type": "string" + } + }, + "required": [ + "integrationName", + "datasets" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "_meta": { + "additionalProperties": false, + "properties": { + "install_source": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "install_source", + "name" + ], + "type": "object" + }, + "items": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "originId": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "dashboard", + "lens", + "visualization", + "search", + "index-pattern", + "map", + "ml-module", + "security-rule", + "csp-rule-template", + "osquery-pack-asset", + "osquery-saved-query", + "tag" + ], + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "type": { + "enum": [ + "index", + "index_template", + "component_template", + "ingest_pipeline", + "ilm_policy", + "data_stream_ilm_policy", + "transform", + "ml_model", + "knowledge_base", + "esql_view" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + } + ] + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items", + "_meta" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Create a custom integration", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/custom_integrations/{pkgName}": { + "put": { + "description": "[Required authorization] Route required privileges: fleet-settings-all AND integrations-all.", + "operationId": "put-fleet-epm-custom-integrations-pkgname", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "categories": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "readMeData": { + "type": "string" + } + }, + "required": [ + "readMeData" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Update a custom integration", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/data_streams": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-read OR fleet-setup OR fleet-all.", + "operationId": "get-fleet-epm-data-streams", + "parameters": [ + { + "in": "query", + "name": "type", + "required": false, + "schema": { + "enum": [ + "logs", + "metrics", + "traces", + "synthetics", + "profiling" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "datasetQuery", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortOrder", + "required": false, + "schema": { + "default": "asc", + "enum": [ + "asc", + "desc" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "uncategorisedOnly", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get data streams", + "tags": [ + "Data streams" + ] + } + }, + "/api/fleet/epm/packages": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-read OR fleet-setup OR fleet-all.", + "operationId": "get-fleet-epm-packages", + "parameters": [ + { + "in": "query", + "name": "category", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "prerelease", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "excludeInstallStatus", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "withPackagePoliciesCount", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": true, + "properties": { + "categories": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "conditions": { + "additionalProperties": true, + "properties": { + "elastic": { + "additionalProperties": true, + "properties": { + "capabilities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "subscription": { + "type": "string" + } + }, + "type": "object" + }, + "kibana": { + "additionalProperties": true, + "properties": { + "version": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "data_streams": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "description": { + "type": "string" + }, + "discovery": { + "additionalProperties": true, + "properties": { + "datasets": { + "items": { + "additionalProperties": true, + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "fields": { + "items": { + "additionalProperties": true, + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + } + }, + "type": "object" + }, + "download": { + "type": "string" + }, + "format_version": { + "type": "string" + }, + "icons": { + "items": { + "additionalProperties": true, + "properties": { + "dark_mode": { + "type": "boolean" + }, + "path": { + "type": "string" + }, + "size": { + "type": "string" + }, + "src": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "src" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "id": { + "type": "string" + }, + "installationInfo": { + "additionalProperties": true, + "properties": { + "additional_spaces_installed_kibana": { + "additionalProperties": { + "items": { + "additionalProperties": true, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "originId": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "dashboard", + "lens", + "visualization", + "search", + "index-pattern", + "map", + "ml-module", + "security-rule", + "csp-rule-template", + "osquery-pack-asset", + "osquery-saved-query", + "tag" + ], + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": "object" + }, + "created_at": { + "type": "string" + }, + "experimental_data_stream_features": { + "items": { + "additionalProperties": true, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": true, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "install_format_schema_version": { + "type": "string" + }, + "install_source": { + "enum": [ + "registry", + "upload", + "bundled", + "custom" + ], + "type": "string" + }, + "install_status": { + "enum": [ + "installed", + "installing", + "install_failed" + ], + "type": "string" + }, + "installed_es": { + "items": { + "additionalProperties": true, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "type": { + "enum": [ + "index", + "index_template", + "component_template", + "ingest_pipeline", + "ilm_policy", + "data_stream_ilm_policy", + "transform", + "ml_model", + "knowledge_base", + "esql_view" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "installed_kibana": { + "items": { + "additionalProperties": true, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "originId": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "dashboard", + "lens", + "visualization", + "search", + "index-pattern", + "map", + "ml-module", + "security-rule", + "csp-rule-template", + "osquery-pack-asset", + "osquery-saved-query", + "tag" + ], + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "installed_kibana_space_id": { + "type": "string" + }, + "is_rollback_ttl_expired": { + "type": "boolean" + }, + "latest_executed_state": { + "additionalProperties": true, + "properties": { + "error": { + "type": "string" + }, + "name": { + "type": "string" + }, + "started_at": { + "type": "string" + } + }, + "type": "object" + }, + "latest_install_failed_attempts": { + "items": { + "additionalProperties": true, + "properties": { + "created_at": { + "type": "string" + }, + "error": { + "additionalProperties": true, + "properties": { + "message": { + "type": "string" + }, + "name": { + "type": "string" + }, + "stack": { + "type": "string" + } + }, + "required": [ + "name", + "message" + ], + "type": "object" + }, + "target_version": { + "type": "string" + } + }, + "required": [ + "created_at", + "target_version", + "error" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "name": { + "type": "string" + }, + "namespaces": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "previous_version": { + "nullable": true, + "type": "string" + }, + "rolled_back": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "verification_key_id": { + "nullable": true, + "type": "string" + }, + "verification_status": { + "enum": [ + "unverified", + "verified", + "unknown" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "type", + "installed_kibana", + "installed_es", + "name", + "version", + "install_status", + "install_source", + "verification_status" + ], + "type": "object" + }, + "integration": { + "type": "string" + }, + "internal": { + "type": "boolean" + }, + "latestVersion": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "additionalProperties": true, + "properties": { + "github": { + "type": "string" + }, + "type": { + "enum": [ + "elastic", + "partner", + "community" + ], + "type": "string" + } + }, + "type": "object" + }, + "path": { + "type": "string" + }, + "policy_templates": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "readme": { + "type": "string" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "signature_path": { + "type": "string" + }, + "source": { + "additionalProperties": true, + "properties": { + "license": { + "type": "string" + } + }, + "required": [ + "license" + ], + "type": "object" + }, + "status": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "integration" + ], + "type": "string" + }, + { + "enum": [ + "input" + ], + "type": "string" + }, + { + "enum": [ + "content" + ], + "type": "string" + }, + { + "type": "string" + } + ] + }, + "vars": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version", + "title", + "id" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get packages", + "tags": [ + "Elastic Package Manager (EPM)" + ] + }, + "post": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "post-fleet-epm-packages", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "query", + "name": "ignoreMappingUpdateErrors", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + }, + { + "in": "query", + "name": "skipDataStreamRollover", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "application/gzip; application/zip": { + "schema": { + "format": "binary", + "type": "string" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/gzip; application/zip": { + "schema": { + "additionalProperties": false, + "properties": { + "_meta": { + "additionalProperties": false, + "properties": { + "install_source": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "install_source", + "name" + ], + "type": "object" + }, + "items": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "originId": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "dashboard", + "lens", + "visualization", + "search", + "index-pattern", + "map", + "ml-module", + "security-rule", + "csp-rule-template", + "osquery-pack-asset", + "osquery-saved-query", + "tag" + ], + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "type": { + "enum": [ + "index", + "index_template", + "component_template", + "ingest_pipeline", + "ilm_policy", + "data_stream_ilm_policy", + "transform", + "ml_model", + "knowledge_base", + "esql_view" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + } + ] + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items", + "_meta" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/gzip; application/zip": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Install a package by upload", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/_bulk": { + "post": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "post-fleet-epm-packages-bulk", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "query", + "name": "prerelease", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "force": { + "default": false, + "type": "boolean" + }, + "packages": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "prerelease": { + "type": "boolean" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + } + ] + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "packages" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "result": { + "additionalProperties": false, + "properties": { + "assets": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "originId": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "dashboard", + "lens", + "visualization", + "search", + "index-pattern", + "map", + "ml-module", + "security-rule", + "csp-rule-template", + "osquery-pack-asset", + "osquery-saved-query", + "tag" + ], + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "type": { + "enum": [ + "index", + "index_template", + "component_template", + "ingest_pipeline", + "ilm_policy", + "data_stream_ilm_policy", + "transform", + "ml_model", + "knowledge_base", + "esql_view" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + } + ] + }, + "maxItems": 10000, + "type": "array" + }, + "error": {}, + "installSource": { + "type": "string" + }, + "installType": { + "type": "string" + }, + "status": { + "enum": [ + "installed", + "already_installed" + ], + "type": "string" + } + }, + "required": [ + "error", + "installType" + ], + "type": "object" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version", + "result" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "error": { + "anyOf": [ + { + "type": "string" + }, + {} + ] + }, + "name": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "name", + "statusCode", + "error" + ], + "type": "object" + } + ] + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk install packages", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/_bulk_rollback": { + "post": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "post-fleet-epm-packages-bulk-rollback", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "bulkRollbackRequest": { + "value": { + "packages": [ + { + "name": "system" + } + ] + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "packages": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "description": "Package name to rollback", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "packages" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "successResponse": { + "value": { + "taskId": "taskId" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "taskId": { + "type": "string" + } + }, + "required": [ + "taskId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "examples": { + "badRequestResponse": { + "value": { + "message": "Bad Request" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk rollback packages", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/_bulk_rollback/{taskId}": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "get-fleet-epm-packages-bulk-rollback-taskid", + "parameters": [ + { + "description": "Task ID of the bulk operation", + "in": "path", + "name": "taskId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "successResponse": { + "value": { + "status": "success" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "results": { + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "name": { + "type": "string" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "name", + "success" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "status": { + "type": "string" + } + }, + "required": [ + "status" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "examples": { + "badRequestResponse": { + "value": { + "message": "Bad Request" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get Bulk rollback packages details", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/_bulk_uninstall": { + "post": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "post-fleet-epm-packages-bulk-uninstall", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "force": { + "default": false, + "type": "boolean" + }, + "packages": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "packages" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "taskId": { + "type": "string" + } + }, + "required": [ + "taskId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk uninstall packages", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/_bulk_uninstall/{taskId}": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "get-fleet-epm-packages-bulk-uninstall-taskid", + "parameters": [ + { + "description": "Task ID of the bulk operation", + "in": "path", + "name": "taskId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "results": { + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "name": { + "type": "string" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "name", + "success" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "status": { + "type": "string" + } + }, + "required": [ + "status" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get Bulk uninstall packages details", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/_bulk_upgrade": { + "post": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "post-fleet-epm-packages-bulk-upgrade", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "force": { + "default": false, + "type": "boolean" + }, + "packages": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "maxItems": 1000, + "minItems": 1, + "type": "array" + }, + "prerelease": { + "type": "boolean" + }, + "upgrade_package_policies": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "packages" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "taskId": { + "type": "string" + } + }, + "required": [ + "taskId" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk upgrade packages", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/_bulk_upgrade/{taskId}": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "get-fleet-epm-packages-bulk-upgrade-taskid", + "parameters": [ + { + "description": "Task ID of the bulk operation", + "in": "path", + "name": "taskId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "results": { + "items": { + "additionalProperties": false, + "properties": { + "error": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "name": { + "type": "string" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "name", + "success" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "status": { + "type": "string" + } + }, + "required": [ + "status" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get Bulk upgrade packages details", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/installed": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-read OR fleet-setup OR fleet-all.", + "operationId": "get-fleet-epm-packages-installed", + "parameters": [ + { + "in": "query", + "name": "dataStreamType", + "required": false, + "schema": { + "enum": [ + "logs", + "metrics", + "traces", + "synthetics", + "profiling" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "showOnlyActiveDataStreams", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "nameQuery", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "searchAfter", + "required": false, + "schema": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "maxItems": 10, + "type": "array" + } + }, + { + "in": "query", + "name": "perPage", + "required": false, + "schema": { + "default": 15, + "type": "number" + } + }, + { + "in": "query", + "name": "sortOrder", + "required": false, + "schema": { + "default": "asc", + "enum": [ + "asc", + "desc" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "dataStreams": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "name", + "title" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "description": { + "type": "string" + }, + "icons": { + "items": { + "additionalProperties": false, + "properties": { + "dark_mode": { + "type": "boolean" + }, + "path": { + "type": "string" + }, + "size": { + "type": "string" + }, + "src": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "src" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "title": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version", + "status", + "dataStreams" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "searchAfter": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "enum": [], + "nullable": true + }, + {} + ] + }, + "maxItems": 2, + "type": "array" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "total" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get installed packages", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/limited": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-read OR fleet-setup OR fleet-all.", + "operationId": "get-fleet-epm-packages-limited", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get a limited package list", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/{pkgName}/rollback": { + "post": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "post-fleet-epm-packages-pkgname-rollback", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "Package name to roll back", + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "successResponse": { + "value": { + "success": true, + "version": "1.0.0" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "success": { + "type": "boolean" + }, + "version": { + "type": "string" + } + }, + "required": [ + "version", + "success" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "examples": { + "badRequestResponse": { + "value": { + "message": "Bad Request" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Rollback a package to previous version", + "tags": [ + "Elastic Package Manager (EPM)" + ], + "x-state": "Technical Preview; added in 9.1.0" + } + }, + "/api/fleet/epm/packages/{pkgName}/stats": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-read OR fleet-setup OR fleet-all.", + "operationId": "get-fleet-epm-packages-pkgname-stats", + "parameters": [ + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "response": { + "additionalProperties": false, + "properties": { + "agent_policy_count": { + "type": "number" + }, + "package_policy_count": { + "type": "number" + } + }, + "required": [ + "agent_policy_count", + "package_policy_count" + ], + "type": "object" + } + }, + "required": [ + "response" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get package stats", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/{pkgName}/{pkgVersion}": { + "delete": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "delete-fleet-epm-packages-pkgname-pkgversion", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pkgVersion", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "force", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "originId": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "dashboard", + "lens", + "visualization", + "search", + "index-pattern", + "map", + "ml-module", + "security-rule", + "csp-rule-template", + "osquery-pack-asset", + "osquery-saved-query", + "tag" + ], + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "type": { + "enum": [ + "index", + "index_template", + "component_template", + "ingest_pipeline", + "ilm_policy", + "data_stream_ilm_policy", + "transform", + "ml_model", + "knowledge_base", + "esql_view" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + } + ] + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Delete a package", + "tags": [ + "Elastic Package Manager (EPM)" + ] + }, + "get": { + "operationId": "get-fleet-epm-packages-pkgname-pkgversion", + "parameters": [ + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pkgVersion", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "ignoreUnverified", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "prerelease", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "full", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "withMetadata", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": true, + "properties": { + "agent": { + "additionalProperties": false, + "properties": { + "privileges": { + "additionalProperties": false, + "properties": { + "root": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "asset_tags": { + "items": { + "additionalProperties": false, + "properties": { + "asset_ids": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "asset_types": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "text": { + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "assets": { + "additionalProperties": {}, + "type": "object" + }, + "categories": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "conditions": { + "additionalProperties": true, + "properties": { + "elastic": { + "additionalProperties": true, + "properties": { + "capabilities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "subscription": { + "type": "string" + } + }, + "type": "object" + }, + "kibana": { + "additionalProperties": true, + "properties": { + "version": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "data_streams": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "description": { + "type": "string" + }, + "discovery": { + "additionalProperties": true, + "properties": { + "datasets": { + "items": { + "additionalProperties": true, + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "fields": { + "items": { + "additionalProperties": true, + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + } + }, + "type": "object" + }, + "download": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": {}, + "type": "object" + }, + "format_version": { + "type": "string" + }, + "icons": { + "items": { + "additionalProperties": true, + "properties": { + "dark_mode": { + "type": "boolean" + }, + "path": { + "type": "string" + }, + "size": { + "type": "string" + }, + "src": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "src" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "installationInfo": { + "additionalProperties": true, + "properties": { + "additional_spaces_installed_kibana": { + "additionalProperties": { + "items": { + "additionalProperties": true, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "originId": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "dashboard", + "lens", + "visualization", + "search", + "index-pattern", + "map", + "ml-module", + "security-rule", + "csp-rule-template", + "osquery-pack-asset", + "osquery-saved-query", + "tag" + ], + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": "object" + }, + "created_at": { + "type": "string" + }, + "experimental_data_stream_features": { + "items": { + "additionalProperties": true, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": true, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "install_format_schema_version": { + "type": "string" + }, + "install_source": { + "enum": [ + "registry", + "upload", + "bundled", + "custom" + ], + "type": "string" + }, + "install_status": { + "enum": [ + "installed", + "installing", + "install_failed" + ], + "type": "string" + }, + "installed_es": { + "items": { + "additionalProperties": true, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "type": { + "enum": [ + "index", + "index_template", + "component_template", + "ingest_pipeline", + "ilm_policy", + "data_stream_ilm_policy", + "transform", + "ml_model", + "knowledge_base", + "esql_view" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "installed_kibana": { + "items": { + "additionalProperties": true, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "originId": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "dashboard", + "lens", + "visualization", + "search", + "index-pattern", + "map", + "ml-module", + "security-rule", + "csp-rule-template", + "osquery-pack-asset", + "osquery-saved-query", + "tag" + ], + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "installed_kibana_space_id": { + "type": "string" + }, + "is_rollback_ttl_expired": { + "type": "boolean" + }, + "latest_executed_state": { + "additionalProperties": true, + "properties": { + "error": { + "type": "string" + }, + "name": { + "type": "string" + }, + "started_at": { + "type": "string" + } + }, + "type": "object" + }, + "latest_install_failed_attempts": { + "items": { + "additionalProperties": true, + "properties": { + "created_at": { + "type": "string" + }, + "error": { + "additionalProperties": true, + "properties": { + "message": { + "type": "string" + }, + "name": { + "type": "string" + }, + "stack": { + "type": "string" + } + }, + "required": [ + "name", + "message" + ], + "type": "object" + }, + "target_version": { + "type": "string" + } + }, + "required": [ + "created_at", + "target_version", + "error" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "name": { + "type": "string" + }, + "namespaces": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "previous_version": { + "nullable": true, + "type": "string" + }, + "rolled_back": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "verification_key_id": { + "nullable": true, + "type": "string" + }, + "verification_status": { + "enum": [ + "unverified", + "verified", + "unknown" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "type", + "installed_kibana", + "installed_es", + "name", + "version", + "install_status", + "install_source", + "verification_status" + ], + "type": "object" + }, + "internal": { + "type": "boolean" + }, + "keepPoliciesUpToDate": { + "type": "boolean" + }, + "latestVersion": { + "type": "string" + }, + "license": { + "type": "string" + }, + "licensePath": { + "type": "string" + }, + "name": { + "type": "string" + }, + "notice": { + "type": "string" + }, + "owner": { + "additionalProperties": true, + "properties": { + "github": { + "type": "string" + }, + "type": { + "enum": [ + "elastic", + "partner", + "community" + ], + "type": "string" + } + }, + "type": "object" + }, + "path": { + "type": "string" + }, + "policy_templates": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "readme": { + "type": "string" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "screenshots": { + "items": { + "additionalProperties": false, + "properties": { + "dark_mode": { + "type": "boolean" + }, + "path": { + "type": "string" + }, + "size": { + "type": "string" + }, + "src": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "src" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "signature_path": { + "type": "string" + }, + "source": { + "additionalProperties": true, + "properties": { + "license": { + "type": "string" + } + }, + "required": [ + "license" + ], + "type": "object" + }, + "status": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "integration" + ], + "type": "string" + }, + { + "enum": [ + "input" + ], + "type": "string" + }, + { + "enum": [ + "content" + ], + "type": "string" + }, + { + "type": "string" + } + ] + }, + "vars": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version", + "title", + "assets" + ], + "type": "object" + }, + "metadata": { + "additionalProperties": false, + "properties": { + "has_policies": { + "type": "boolean" + } + }, + "required": [ + "has_policies" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get a package", + "tags": [ + "Elastic Package Manager (EPM)" + ] + }, + "post": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "post-fleet-epm-packages-pkgname-pkgversion", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pkgVersion", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "prerelease", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "ignoreMappingUpdateErrors", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + }, + { + "in": "query", + "name": "skipDataStreamRollover", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "nullable": true, + "properties": { + "force": { + "default": false, + "type": "boolean" + }, + "ignore_constraints": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "_meta": { + "additionalProperties": false, + "properties": { + "install_source": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "install_source", + "name" + ], + "type": "object" + }, + "items": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "originId": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "dashboard", + "lens", + "visualization", + "search", + "index-pattern", + "map", + "ml-module", + "security-rule", + "csp-rule-template", + "osquery-pack-asset", + "osquery-saved-query", + "tag" + ], + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "type": { + "enum": [ + "index", + "index_template", + "component_template", + "ingest_pipeline", + "ilm_policy", + "data_stream_ilm_policy", + "transform", + "ml_model", + "knowledge_base", + "esql_view" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + } + ] + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items", + "_meta" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Install a package from the registry", + "tags": [ + "Elastic Package Manager (EPM)" + ] + }, + "put": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "put-fleet-epm-packages-pkgname-pkgversion", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pkgVersion", + "required": false, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "keepPoliciesUpToDate": { + "type": "boolean" + } + }, + "required": [ + "keepPoliciesUpToDate" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": true, + "properties": { + "agent": { + "additionalProperties": false, + "properties": { + "privileges": { + "additionalProperties": false, + "properties": { + "root": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "asset_tags": { + "items": { + "additionalProperties": false, + "properties": { + "asset_ids": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "asset_types": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "text": { + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "assets": { + "additionalProperties": {}, + "type": "object" + }, + "categories": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "conditions": { + "additionalProperties": true, + "properties": { + "elastic": { + "additionalProperties": true, + "properties": { + "capabilities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "subscription": { + "type": "string" + } + }, + "type": "object" + }, + "kibana": { + "additionalProperties": true, + "properties": { + "version": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "data_streams": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "description": { + "type": "string" + }, + "discovery": { + "additionalProperties": true, + "properties": { + "datasets": { + "items": { + "additionalProperties": true, + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "fields": { + "items": { + "additionalProperties": true, + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + } + }, + "type": "object" + }, + "download": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": {}, + "type": "object" + }, + "format_version": { + "type": "string" + }, + "icons": { + "items": { + "additionalProperties": true, + "properties": { + "dark_mode": { + "type": "boolean" + }, + "path": { + "type": "string" + }, + "size": { + "type": "string" + }, + "src": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "src" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "installationInfo": { + "additionalProperties": true, + "properties": { + "additional_spaces_installed_kibana": { + "additionalProperties": { + "items": { + "additionalProperties": true, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "originId": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "dashboard", + "lens", + "visualization", + "search", + "index-pattern", + "map", + "ml-module", + "security-rule", + "csp-rule-template", + "osquery-pack-asset", + "osquery-saved-query", + "tag" + ], + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": "object" + }, + "created_at": { + "type": "string" + }, + "experimental_data_stream_features": { + "items": { + "additionalProperties": true, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": true, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "install_format_schema_version": { + "type": "string" + }, + "install_source": { + "enum": [ + "registry", + "upload", + "bundled", + "custom" + ], + "type": "string" + }, + "install_status": { + "enum": [ + "installed", + "installing", + "install_failed" + ], + "type": "string" + }, + "installed_es": { + "items": { + "additionalProperties": true, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "type": { + "enum": [ + "index", + "index_template", + "component_template", + "ingest_pipeline", + "ilm_policy", + "data_stream_ilm_policy", + "transform", + "ml_model", + "knowledge_base", + "esql_view" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "installed_kibana": { + "items": { + "additionalProperties": true, + "properties": { + "deferred": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "originId": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "dashboard", + "lens", + "visualization", + "search", + "index-pattern", + "map", + "ml-module", + "security-rule", + "csp-rule-template", + "osquery-pack-asset", + "osquery-saved-query", + "tag" + ], + "type": "string" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "installed_kibana_space_id": { + "type": "string" + }, + "is_rollback_ttl_expired": { + "type": "boolean" + }, + "latest_executed_state": { + "additionalProperties": true, + "properties": { + "error": { + "type": "string" + }, + "name": { + "type": "string" + }, + "started_at": { + "type": "string" + } + }, + "type": "object" + }, + "latest_install_failed_attempts": { + "items": { + "additionalProperties": true, + "properties": { + "created_at": { + "type": "string" + }, + "error": { + "additionalProperties": true, + "properties": { + "message": { + "type": "string" + }, + "name": { + "type": "string" + }, + "stack": { + "type": "string" + } + }, + "required": [ + "name", + "message" + ], + "type": "object" + }, + "target_version": { + "type": "string" + } + }, + "required": [ + "created_at", + "target_version", + "error" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "name": { + "type": "string" + }, + "namespaces": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "previous_version": { + "nullable": true, + "type": "string" + }, + "rolled_back": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "verification_key_id": { + "nullable": true, + "type": "string" + }, + "verification_status": { + "enum": [ + "unverified", + "verified", + "unknown" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "type", + "installed_kibana", + "installed_es", + "name", + "version", + "install_status", + "install_source", + "verification_status" + ], + "type": "object" + }, + "internal": { + "type": "boolean" + }, + "keepPoliciesUpToDate": { + "type": "boolean" + }, + "latestVersion": { + "type": "string" + }, + "license": { + "type": "string" + }, + "licensePath": { + "type": "string" + }, + "name": { + "type": "string" + }, + "notice": { + "type": "string" + }, + "owner": { + "additionalProperties": true, + "properties": { + "github": { + "type": "string" + }, + "type": { + "enum": [ + "elastic", + "partner", + "community" + ], + "type": "string" + } + }, + "type": "object" + }, + "path": { + "type": "string" + }, + "policy_templates": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "readme": { + "type": "string" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "screenshots": { + "items": { + "additionalProperties": false, + "properties": { + "dark_mode": { + "type": "boolean" + }, + "path": { + "type": "string" + }, + "size": { + "type": "string" + }, + "src": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "src" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "signature_path": { + "type": "string" + }, + "source": { + "additionalProperties": true, + "properties": { + "license": { + "type": "string" + } + }, + "required": [ + "license" + ], + "type": "object" + }, + "status": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "anyOf": [ + { + "enum": [ + "integration" + ], + "type": "string" + }, + { + "enum": [ + "input" + ], + "type": "string" + }, + { + "enum": [ + "content" + ], + "type": "string" + }, + { + "type": "string" + } + ] + }, + "vars": { + "items": { + "additionalProperties": {}, + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version", + "title", + "assets" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Update package settings", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/{pkgName}/{pkgVersion}/datastream_assets": { + "delete": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "delete-fleet-epm-packages-pkgname-pkgversion-datastream-assets", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pkgVersion", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "packagePolicyId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "success": { + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Delete assets for an input package", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/{pkgName}/{pkgVersion}/kibana_assets": { + "delete": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "delete-fleet-epm-packages-pkgname-pkgversion-kibana-assets", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pkgVersion", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "success": { + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Delete Kibana assets for a package", + "tags": [ + "Elastic Package Manager (EPM)" + ] + }, + "post": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "post-fleet-epm-packages-pkgname-pkgversion-kibana-assets", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pkgVersion", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "nullable": true, + "properties": { + "force": { + "type": "boolean" + }, + "space_ids": { + "description": "When provided install assets in the specified spaces instead of the current space.", + "items": { + "type": "string" + }, + "maxItems": 100, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "success": { + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Install Kibana assets for a package", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/{pkgName}/{pkgVersion}/rule_assets": { + "post": { + "description": "[Required authorization] Route required privileges: integrations-all AND fleet-agent-policies-all.", + "operationId": "post-fleet-epm-packages-pkgname-pkgversion-rule-assets", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pkgVersion", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "nullable": true, + "properties": { + "force": { + "type": "boolean" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "success": { + "type": "boolean" + } + }, + "required": [ + "success" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Install Kibana alert rule for a package", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/{pkgName}/{pkgVersion}/transforms/authorize": { + "post": { + "operationId": "post-fleet-epm-packages-pkgname-pkgversion-transforms-authorize", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pkgVersion", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "prerelease", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "transforms": { + "items": { + "additionalProperties": false, + "properties": { + "transformId": { + "type": "string" + } + }, + "required": [ + "transformId" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + } + }, + "required": [ + "transforms" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "additionalProperties": false, + "properties": { + "error": { + "nullable": true + }, + "success": { + "type": "boolean" + }, + "transformId": { + "type": "string" + } + }, + "required": [ + "transformId", + "success", + "error" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Authorize transforms", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/packages/{pkgName}/{pkgVersion}/{filePath}": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-read OR fleet-setup OR fleet-all.", + "operationId": "get-fleet-epm-packages-pkgname-pkgversion-filepath", + "parameters": [ + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pkgVersion", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "filePath", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": {} + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get a package file", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/templates/{pkgName}/{pkgVersion}/inputs": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-read OR fleet-setup OR fleet-all.", + "operationId": "get-fleet-epm-templates-pkgname-pkgversion-inputs", + "parameters": [ + { + "in": "path", + "name": "pkgName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pkgVersion", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "format", + "required": false, + "schema": { + "default": "json", + "enum": [ + "json", + "yml", + "yaml" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "prerelease", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "ignoreUnverified", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "inputs": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": true, + "properties": { + "data_stream": { + "additionalProperties": true, + "properties": { + "dataset": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset" + ], + "type": "object" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id", + "data_stream" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "inputs" + ], + "type": "object" + } + ] + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get an inputs template", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/epm/verification_key_id": { + "get": { + "description": "[Required authorization] Route required privileges: integrations-read OR fleet-setup OR fleet-all.", + "operationId": "get-fleet-epm-verification-key-id", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "id": { + "nullable": true, + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get a package signature verification key ID", + "tags": [ + "Elastic Package Manager (EPM)" + ] + } + }, + "/api/fleet/fleet_server_hosts": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agents-all OR fleet-settings-read.", + "operationId": "get-fleet-fleet-server-hosts", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "host_urls": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "agent_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "es_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "agent_certificate": { + "type": "string" + }, + "agent_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "agent_key": { + "type": "string" + }, + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "client_auth": { + "enum": [ + "optional", + "required", + "none" + ], + "type": "string" + }, + "es_certificate": { + "type": "string" + }, + "es_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "es_key": { + "type": "string" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "name", + "host_urls", + "id" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "page": { + "type": "number" + }, + "perPage": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "total", + "page", + "perPage" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get Fleet Server hosts", + "tags": [ + "Fleet Server hosts" + ] + }, + "post": { + "description": "[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "post-fleet-fleet-server-hosts", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "host_urls": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "agent_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "es_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "agent_certificate": { + "type": "string" + }, + "agent_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "agent_key": { + "type": "string" + }, + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "client_auth": { + "enum": [ + "optional", + "required", + "none" + ], + "type": "string" + }, + "es_certificate": { + "type": "string" + }, + "es_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "es_key": { + "type": "string" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "name", + "host_urls" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "host_urls": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "agent_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "es_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "agent_certificate": { + "type": "string" + }, + "agent_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "agent_key": { + "type": "string" + }, + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "client_auth": { + "enum": [ + "optional", + "required", + "none" + ], + "type": "string" + }, + "es_certificate": { + "type": "string" + }, + "es_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "es_key": { + "type": "string" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "name", + "host_urls", + "id" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Create a Fleet Server host", + "tags": [ + "Fleet Server hosts" + ] + } + }, + "/api/fleet/fleet_server_hosts/{itemId}": { + "delete": { + "description": "Delete a Fleet Server host by ID.

[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "delete-fleet-fleet-server-hosts-itemid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "itemId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Delete a Fleet Server host", + "tags": [ + "Fleet Server hosts" + ] + }, + "get": { + "description": "Get a Fleet Server host by ID.

[Required authorization] Route required privileges: fleet-settings-read.", + "operationId": "get-fleet-fleet-server-hosts-itemid", + "parameters": [ + { + "in": "path", + "name": "itemId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "host_urls": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "agent_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "es_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "agent_certificate": { + "type": "string" + }, + "agent_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "agent_key": { + "type": "string" + }, + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "client_auth": { + "enum": [ + "optional", + "required", + "none" + ], + "type": "string" + }, + "es_certificate": { + "type": "string" + }, + "es_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "es_key": { + "type": "string" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "name", + "host_urls", + "id" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get a Fleet Server host", + "tags": [ + "Fleet Server hosts" + ] + }, + "put": { + "description": "Update a Fleet Server host by ID.

[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "put-fleet-fleet-server-hosts-itemid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "itemId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "host_urls": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "is_default": { + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "agent_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "es_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "agent_certificate": { + "type": "string" + }, + "agent_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "agent_key": { + "type": "string" + }, + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "client_auth": { + "enum": [ + "optional", + "required", + "none" + ], + "type": "string" + }, + "es_certificate": { + "type": "string" + }, + "es_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "es_key": { + "type": "string" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "proxy_id" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "host_urls": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "agent_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "es_key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "agent_certificate": { + "type": "string" + }, + "agent_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "agent_key": { + "type": "string" + }, + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "client_auth": { + "enum": [ + "optional", + "required", + "none" + ], + "type": "string" + }, + "es_certificate": { + "type": "string" + }, + "es_certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "es_key": { + "type": "string" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "name", + "host_urls", + "id" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Update a Fleet Server host", + "tags": [ + "Fleet Server hosts" + ] + } + }, + "/api/fleet/health_check": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "post-fleet-health-check", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "host_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "type": "string" + } + }, + "required": [ + "status" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "404": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "Not found." + } + }, + "summary": "Check Fleet Server health", + "tags": [ + "Fleet internals" + ] + } + }, + "/api/fleet/kubernetes": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-read OR fleet-setup.", + "operationId": "get-fleet-kubernetes", + "parameters": [ + { + "in": "query", + "name": "download", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "fleetServer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "enrolToken", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "type": "string" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get a full K8s agent manifest", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/kubernetes/download": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-read OR fleet-setup.", + "operationId": "get-fleet-kubernetes-download", + "parameters": [ + { + "in": "query", + "name": "download", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "fleetServer", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "enrolToken", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "404": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "Not found." + } + }, + "summary": "Download an agent manifest", + "tags": [ + "Elastic Agent policies" + ] + } + }, + "/api/fleet/logstash_api_keys": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "post-fleet-logstash-api-keys", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "api_key": { + "type": "string" + } + }, + "required": [ + "api_key" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Generate a Logstash API key", + "tags": [ + "Fleet outputs" + ] + } + }, + "/api/fleet/message_signing_service/rotate_key_pair": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all AND fleet-agent-policies-all AND fleet-settings-all.", + "operationId": "post-fleet-message-signing-service-rotate-key-pair", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "query", + "name": "acknowledge", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "500": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "An internal server error." + } + }, + "summary": "Rotate a Fleet message signing key pair", + "tags": [ + "Message Signing Service" + ] + } + }, + "/api/fleet/outputs": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-settings-read OR fleet-agent-policies-read.", + "operationId": "get-fleet-outputs", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "kibana_api_key": { + "nullable": true, + "type": "string" + }, + "kibana_url": { + "nullable": true, + "type": "string" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "service_token": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "service_token": { + "nullable": true, + "type": "string" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "sync_integrations": { + "type": "boolean" + }, + "sync_uninstalled_integrations": { + "type": "boolean" + }, + "type": { + "enum": [ + "remote_elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "logstash" + ], + "type": "string" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "auth_type": { + "enum": [ + "none", + "user_pass", + "ssl", + "kerberos" + ], + "type": "string" + }, + "broker_timeout": { + "type": "number" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "client_id": { + "type": "string" + }, + "compression": { + "enum": [ + "gzip", + "snappy", + "lz4", + "none" + ], + "type": "string" + }, + "compression_level": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "number" + }, + { + "not": {} + } + ] + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "connection_type": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "enum": [ + "plaintext", + "encryption" + ], + "type": "string" + }, + { + "not": {} + } + ] + }, + "hash": { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "random": { + "type": "boolean" + } + }, + "type": "object" + }, + "headers": { + "items": { + "additionalProperties": true, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "partition": { + "enum": [ + "random", + "round_robin", + "hash" + ], + "type": "string" + }, + "password": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "not": {} + }, + { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + } + ] + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "random": { + "additionalProperties": true, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "required_acks": { + "enum": [ + 1, + 0, + -1 + ], + "type": "integer" + }, + "round_robin": { + "additionalProperties": true, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "sasl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "mechanism": { + "enum": [ + "PLAIN", + "SCRAM-SHA-256", + "SCRAM-SHA-512" + ], + "type": "string" + } + }, + "type": "object" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "password": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "timeout": { + "type": "number" + }, + "topic": { + "type": "string" + }, + "type": { + "enum": [ + "kafka" + ], + "type": "string" + }, + "username": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "type", + "hosts", + "compression_level", + "auth_type", + "connection_type", + "username", + "password" + ], + "type": "object" + } + ] + }, + "maxItems": 10000, + "type": "array" + }, + "page": { + "type": "number" + }, + "perPage": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "total", + "page", + "perPage" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get outputs", + "tags": [ + "Fleet outputs" + ] + }, + "post": { + "description": "[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "post-fleet-outputs", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": false, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "kibana_api_key": { + "nullable": true, + "type": "string" + }, + "kibana_url": { + "nullable": true, + "type": "string" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "service_token": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "service_token": { + "nullable": true, + "type": "string" + }, + "shipper": { + "additionalProperties": false, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "sync_integrations": { + "type": "boolean" + }, + "sync_uninstalled_integrations": { + "type": "boolean" + }, + "type": { + "enum": [ + "remote_elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": false, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "logstash" + ], + "type": "string" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "auth_type": { + "enum": [ + "none", + "user_pass", + "ssl", + "kerberos" + ], + "type": "string" + }, + "broker_timeout": { + "type": "number" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "client_id": { + "type": "string" + }, + "compression": { + "enum": [ + "gzip", + "snappy", + "lz4", + "none" + ], + "type": "string" + }, + "compression_level": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "number" + }, + { + "not": {} + } + ] + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "connection_type": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "enum": [ + "plaintext", + "encryption" + ], + "type": "string" + }, + { + "not": {} + } + ] + }, + "hash": { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "random": { + "type": "boolean" + } + }, + "type": "object" + }, + "headers": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "partition": { + "enum": [ + "random", + "round_robin", + "hash" + ], + "type": "string" + }, + "password": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "not": {} + }, + { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + } + ] + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "random": { + "additionalProperties": false, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "required_acks": { + "enum": [ + 1, + 0, + -1 + ], + "type": "integer" + }, + "round_robin": { + "additionalProperties": false, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "sasl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "mechanism": { + "enum": [ + "PLAIN", + "SCRAM-SHA-256", + "SCRAM-SHA-512" + ], + "type": "string" + } + }, + "type": "object" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "password": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": false, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "timeout": { + "type": "number" + }, + "topic": { + "type": "string" + }, + "type": { + "enum": [ + "kafka" + ], + "type": "string" + }, + "username": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "type", + "hosts", + "compression_level", + "auth_type", + "connection_type", + "username", + "password" + ], + "type": "object" + } + ] + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "kibana_api_key": { + "nullable": true, + "type": "string" + }, + "kibana_url": { + "nullable": true, + "type": "string" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "service_token": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "service_token": { + "nullable": true, + "type": "string" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "sync_integrations": { + "type": "boolean" + }, + "sync_uninstalled_integrations": { + "type": "boolean" + }, + "type": { + "enum": [ + "remote_elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "logstash" + ], + "type": "string" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "auth_type": { + "enum": [ + "none", + "user_pass", + "ssl", + "kerberos" + ], + "type": "string" + }, + "broker_timeout": { + "type": "number" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "client_id": { + "type": "string" + }, + "compression": { + "enum": [ + "gzip", + "snappy", + "lz4", + "none" + ], + "type": "string" + }, + "compression_level": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "number" + }, + { + "not": {} + } + ] + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "connection_type": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "enum": [ + "plaintext", + "encryption" + ], + "type": "string" + }, + { + "not": {} + } + ] + }, + "hash": { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "random": { + "type": "boolean" + } + }, + "type": "object" + }, + "headers": { + "items": { + "additionalProperties": true, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "partition": { + "enum": [ + "random", + "round_robin", + "hash" + ], + "type": "string" + }, + "password": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "not": {} + }, + { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + } + ] + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "random": { + "additionalProperties": true, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "required_acks": { + "enum": [ + 1, + 0, + -1 + ], + "type": "integer" + }, + "round_robin": { + "additionalProperties": true, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "sasl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "mechanism": { + "enum": [ + "PLAIN", + "SCRAM-SHA-256", + "SCRAM-SHA-512" + ], + "type": "string" + } + }, + "type": "object" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "password": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "timeout": { + "type": "number" + }, + "topic": { + "type": "string" + }, + "type": { + "enum": [ + "kafka" + ], + "type": "string" + }, + "username": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "type", + "hosts", + "compression_level", + "auth_type", + "connection_type", + "username", + "password" + ], + "type": "object" + } + ] + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Create output", + "tags": [ + "Fleet outputs" + ] + } + }, + "/api/fleet/outputs/{outputId}": { + "delete": { + "description": "Delete output by ID.

[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "delete-fleet-outputs-outputid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "outputId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "404": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "Not found." + } + }, + "summary": "Delete output", + "tags": [ + "Fleet outputs" + ] + }, + "get": { + "description": "Get output by ID.

[Required authorization] Route required privileges: fleet-settings-read OR fleet-agent-policies-read.", + "operationId": "get-fleet-outputs-outputid", + "parameters": [ + { + "in": "path", + "name": "outputId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "kibana_api_key": { + "nullable": true, + "type": "string" + }, + "kibana_url": { + "nullable": true, + "type": "string" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "service_token": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "service_token": { + "nullable": true, + "type": "string" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "sync_integrations": { + "type": "boolean" + }, + "sync_uninstalled_integrations": { + "type": "boolean" + }, + "type": { + "enum": [ + "remote_elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "logstash" + ], + "type": "string" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "auth_type": { + "enum": [ + "none", + "user_pass", + "ssl", + "kerberos" + ], + "type": "string" + }, + "broker_timeout": { + "type": "number" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "client_id": { + "type": "string" + }, + "compression": { + "enum": [ + "gzip", + "snappy", + "lz4", + "none" + ], + "type": "string" + }, + "compression_level": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "number" + }, + { + "not": {} + } + ] + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "connection_type": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "enum": [ + "plaintext", + "encryption" + ], + "type": "string" + }, + { + "not": {} + } + ] + }, + "hash": { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "random": { + "type": "boolean" + } + }, + "type": "object" + }, + "headers": { + "items": { + "additionalProperties": true, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "partition": { + "enum": [ + "random", + "round_robin", + "hash" + ], + "type": "string" + }, + "password": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "not": {} + }, + { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + } + ] + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "random": { + "additionalProperties": true, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "required_acks": { + "enum": [ + 1, + 0, + -1 + ], + "type": "integer" + }, + "round_robin": { + "additionalProperties": true, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "sasl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "mechanism": { + "enum": [ + "PLAIN", + "SCRAM-SHA-256", + "SCRAM-SHA-512" + ], + "type": "string" + } + }, + "type": "object" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "password": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "timeout": { + "type": "number" + }, + "topic": { + "type": "string" + }, + "type": { + "enum": [ + "kafka" + ], + "type": "string" + }, + "username": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "type", + "hosts", + "compression_level", + "auth_type", + "connection_type", + "username", + "password" + ], + "type": "object" + } + ] + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get output", + "tags": [ + "Fleet outputs" + ] + }, + "put": { + "description": "Update output by ID.

[Required authorization] Route required privileges: fleet-settings-all OR fleet-agent-policies-all.", + "operationId": "put-fleet-outputs-outputid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "outputId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "type": "boolean" + }, + "is_default_monitoring": { + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": false, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "type": "boolean" + }, + "is_default_monitoring": { + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "kibana_api_key": { + "nullable": true, + "type": "string" + }, + "kibana_url": { + "nullable": true, + "type": "string" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "service_token": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "service_token": { + "nullable": true, + "type": "string" + }, + "shipper": { + "additionalProperties": false, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "sync_integrations": { + "type": "boolean" + }, + "sync_uninstalled_integrations": { + "type": "boolean" + }, + "type": { + "enum": [ + "remote_elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "type": "boolean" + }, + "is_default_monitoring": { + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": false, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "logstash" + ], + "type": "string" + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "auth_type": { + "enum": [ + "none", + "user_pass", + "ssl", + "kerberos" + ], + "type": "string" + }, + "broker_timeout": { + "type": "number" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "client_id": { + "type": "string" + }, + "compression": { + "enum": [ + "gzip", + "snappy", + "lz4", + "none" + ], + "type": "string" + }, + "compression_level": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "number" + }, + { + "not": {} + } + ] + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "connection_type": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "enum": [ + "plaintext", + "encryption" + ], + "type": "string" + }, + { + "not": {} + } + ] + }, + "hash": { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "random": { + "type": "boolean" + } + }, + "type": "object" + }, + "headers": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "partition": { + "enum": [ + "random", + "round_robin", + "hash" + ], + "type": "string" + }, + "password": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "not": {} + }, + { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + } + ] + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "random": { + "additionalProperties": false, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "required_acks": { + "enum": [ + 1, + 0, + -1 + ], + "type": "integer" + }, + "round_robin": { + "additionalProperties": false, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "sasl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "mechanism": { + "enum": [ + "PLAIN", + "SCRAM-SHA-256", + "SCRAM-SHA-512" + ], + "type": "string" + } + }, + "type": "object" + }, + "secrets": { + "additionalProperties": false, + "properties": { + "password": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": false, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": false, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": false, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "timeout": { + "type": "number" + }, + "topic": { + "type": "string" + }, + "type": { + "enum": [ + "kafka" + ], + "type": "string" + }, + "username": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "compression_level", + "connection_type", + "username", + "password" + ], + "type": "object" + } + ] + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "kibana_api_key": { + "nullable": true, + "type": "string" + }, + "kibana_url": { + "nullable": true, + "type": "string" + }, + "name": { + "type": "string" + }, + "preset": { + "enum": [ + "balanced", + "custom", + "throughput", + "scale", + "latency" + ], + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "service_token": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "service_token": { + "nullable": true, + "type": "string" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "sync_integrations": { + "type": "boolean" + }, + "sync_uninstalled_integrations": { + "type": "boolean" + }, + "type": { + "enum": [ + "remote_elasticsearch" + ], + "type": "string" + }, + "write_to_logs_streams": { + "nullable": true, + "type": "boolean" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "enum": [ + "logstash" + ], + "type": "string" + } + }, + "required": [ + "name", + "type", + "hosts" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "allow_edit": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "auth_type": { + "enum": [ + "none", + "user_pass", + "ssl", + "kerberos" + ], + "type": "string" + }, + "broker_timeout": { + "type": "number" + }, + "ca_sha256": { + "nullable": true, + "type": "string" + }, + "ca_trusted_fingerprint": { + "nullable": true, + "type": "string" + }, + "client_id": { + "type": "string" + }, + "compression": { + "enum": [ + "gzip", + "snappy", + "lz4", + "none" + ], + "type": "string" + }, + "compression_level": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "number" + }, + { + "not": {} + } + ] + }, + "config_yaml": { + "nullable": true, + "type": "string" + }, + "connection_type": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "enum": [ + "plaintext", + "encryption" + ], + "type": "string" + }, + { + "not": {} + } + ] + }, + "hash": { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "random": { + "type": "boolean" + } + }, + "type": "object" + }, + "headers": { + "items": { + "additionalProperties": true, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "hosts": { + "items": { + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" + }, + "id": { + "type": "string" + }, + "is_default": { + "default": false, + "type": "boolean" + }, + "is_default_monitoring": { + "default": false, + "type": "boolean" + }, + "is_internal": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "partition": { + "enum": [ + "random", + "round_robin", + "hash" + ], + "type": "string" + }, + "password": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "not": {} + }, + { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + } + ] + }, + "proxy_id": { + "nullable": true, + "type": "string" + }, + "random": { + "additionalProperties": true, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "required_acks": { + "enum": [ + 1, + 0, + -1 + ], + "type": "integer" + }, + "round_robin": { + "additionalProperties": true, + "properties": { + "group_events": { + "type": "number" + } + }, + "type": "object" + }, + "sasl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "mechanism": { + "enum": [ + "PLAIN", + "SCRAM-SHA-256", + "SCRAM-SHA-512" + ], + "type": "string" + } + }, + "type": "object" + }, + "secrets": { + "additionalProperties": true, + "properties": { + "password": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + }, + "ssl": { + "additionalProperties": true, + "properties": { + "key": { + "anyOf": [ + { + "additionalProperties": true, + "properties": { + "hash": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "key" + ], + "type": "object" + } + }, + "type": "object" + }, + "shipper": { + "additionalProperties": true, + "nullable": true, + "properties": { + "compression_level": { + "nullable": true, + "type": "number" + }, + "disk_queue_compression_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_enabled": { + "default": false, + "nullable": true, + "type": "boolean" + }, + "disk_queue_encryption_enabled": { + "nullable": true, + "type": "boolean" + }, + "disk_queue_max_size": { + "nullable": true, + "type": "number" + }, + "disk_queue_path": { + "nullable": true, + "type": "string" + }, + "loadbalance": { + "nullable": true, + "type": "boolean" + }, + "max_batch_bytes": { + "nullable": true, + "type": "number" + }, + "mem_queue_events": { + "nullable": true, + "type": "number" + }, + "queue_flush_timeout": { + "nullable": true, + "type": "number" + } + }, + "required": [ + "disk_queue_path", + "disk_queue_max_size", + "disk_queue_encryption_enabled", + "disk_queue_compression_enabled", + "compression_level", + "loadbalance", + "mem_queue_events", + "queue_flush_timeout", + "max_batch_bytes" + ], + "type": "object" + }, + "ssl": { + "additionalProperties": true, + "nullable": true, + "properties": { + "certificate": { + "type": "string" + }, + "certificate_authorities": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "key": { + "type": "string" + }, + "verification_mode": { + "enum": [ + "full", + "none", + "certificate", + "strict" + ], + "type": "string" + } + }, + "type": "object" + }, + "timeout": { + "type": "number" + }, + "topic": { + "type": "string" + }, + "type": { + "enum": [ + "kafka" + ], + "type": "string" + }, + "username": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "type": "string" + }, + { + "not": {} + } + ] + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "type", + "hosts", + "compression_level", + "auth_type", + "connection_type", + "username", + "password" + ], + "type": "object" + } + ] + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Update output", + "tags": [ + "Fleet outputs" + ] + } + }, + "/api/fleet/outputs/{outputId}/health": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-settings-read.", + "operationId": "get-fleet-outputs-outputid-health", + "parameters": [ + { + "in": "path", + "name": "outputId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "message": { + "description": "long message if unhealthy", + "type": "string" + }, + "state": { + "description": "state of output, HEALTHY or DEGRADED", + "type": "string" + }, + "timestamp": { + "description": "timestamp of reported state", + "type": "string" + } + }, + "required": [ + "state", + "message", + "timestamp" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get the latest output health", + "tags": [ + "Fleet outputs" + ] + } + }, + "/api/fleet/package_policies": { + "get": { + "operationId": "get-fleet-package-policies", + "parameters": [ + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "perPage", + "required": false, + "schema": { + "type": "number" + } + }, + { + "in": "query", + "name": "sortField", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "sortOrder", + "required": false, + "schema": { + "enum": [ + "desc", + "asc" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "showUpgradeable", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "kuery", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "format", + "required": false, + "schema": { + "enum": [ + "simplified", + "legacy" + ], + "type": "string" + } + }, + { + "in": "query", + "name": "withAgentCount", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "page": { + "type": "number" + }, + "perPage": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "total", + "page", + "perPage" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get package policies", + "tags": [ + "Fleet package policies" + ] + }, + "post": { + "operationId": "post-fleet-package-policies", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "query", + "name": "format", + "required": false, + "schema": { + "enum": [ + "simplified", + "legacy" + ], + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "force": { + "description": "Force package policy creation even if the package is not verified, or if the agent policy is managed.", + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier", + "type": "string" + }, + "inputs": { + "items": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled" + ], + "type": "object" + }, + "maxItems": 1000, + "type": "array" + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "deprecated": true, + "description": "Indicates whether the package policy belongs to an agentless agent policy. Deprecated in favor of the Fleet agentless policies API.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "name", + "inputs" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 100, + "nullable": true, + "type": "array" + }, + "description": { + "description": "Policy description.", + "type": "string" + }, + "force": { + "description": "Force package policy creation even if the package is not verified, or if the agent policy is managed.", + "type": "boolean" + }, + "id": { + "description": "Policy unique identifier.", + "type": "string" + }, + "inputs": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object" + }, + "name": { + "description": "Unique name for the policy.", + "type": "string" + }, + "namespace": { + "description": "Policy namespace. When not specified, it inherits the agent policy namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "Deprecated. Use policy_ids instead.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "description": "IDs of the agent policies which that package policy will be added to.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "supports_agentless": { + "default": false, + "deprecated": true, + "description": "Indicates whether the package policy belongs to an agentless agent policy. Deprecated in favor of the Fleet agentless policies API.", + "nullable": true, + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "required": [ + "name", + "package" + ], + "type": "object" + } + ], + "description": "You should use inputs as an object and not use the deprecated inputs array." + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "409": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A conflict occurred." + } + }, + "summary": "Create a package policy", + "tags": [ + "Fleet package policies" + ] + } + }, + "/api/fleet/package_policies/_bulk_get": { + "post": { + "operationId": "post-fleet-package-policies-bulk-get", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "query", + "name": "format", + "required": false, + "schema": { + "enum": [ + "simplified", + "legacy" + ], + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "ids": { + "description": "list of package policy ids", + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "ignoreMissing": { + "type": "boolean" + } + }, + "required": [ + "ids" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "404": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + }, + "description": "Not found." + } + }, + "summary": "Bulk get package policies", + "tags": [ + "Fleet package policies" + ] + } + }, + "/api/fleet/package_policies/delete": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-all AND integrations-all.", + "operationId": "post-fleet-package-policies-delete", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "force": { + "type": "boolean" + }, + "packagePolicyIds": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + } + }, + "required": [ + "packagePolicyIds" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "additionalProperties": false, + "properties": { + "body": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "Use `policy_ids` instead", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "type": "string" + }, + "maxItems": 10000, + "type": "array" + }, + "statusCode": { + "type": "number" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "id", + "success", + "policy_ids", + "package" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Bulk delete package policies", + "tags": [ + "Fleet package policies" + ] + } + }, + "/api/fleet/package_policies/upgrade": { + "post": { + "description": "Upgrade a package policy to a newer package version.

[Required authorization] Route required privileges: fleet-agent-policies-all AND integrations-all.", + "operationId": "post-fleet-package-policies-upgrade", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "packagePolicyIds": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + } + }, + "required": [ + "packagePolicyIds" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "additionalProperties": false, + "properties": { + "body": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "statusCode": { + "type": "number" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "id", + "success" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Upgrade a package policy", + "tags": [ + "Fleet package policies" + ] + } + }, + "/api/fleet/package_policies/upgrade/dryrun": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agent-policies-read AND integrations-read.", + "operationId": "post-fleet-package-policies-upgrade-dryrun", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "packagePolicyIds": { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "packageVersion": { + "type": "string" + } + }, + "required": [ + "packagePolicyIds" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "additionalProperties": false, + "properties": { + "agent_diff": { + "items": { + "items": { + "additionalProperties": true, + "properties": { + "data_stream": { + "additionalProperties": true, + "properties": { + "namespace": { + "type": "string" + } + }, + "required": [ + "namespace" + ], + "type": "object" + }, + "id": { + "type": "string" + }, + "meta": { + "additionalProperties": true, + "properties": { + "package": { + "additionalProperties": true, + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + } + }, + "required": [ + "package" + ], + "type": "object" + }, + "name": { + "type": "string" + }, + "package_policy_id": { + "type": "string" + }, + "processors": { + "items": { + "additionalProperties": true, + "properties": { + "add_fields": { + "additionalProperties": true, + "properties": { + "fields": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "type": "object" + }, + "target": { + "type": "string" + } + }, + "required": [ + "target", + "fields" + ], + "type": "object" + } + }, + "required": [ + "add_fields" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "revision": { + "type": "number" + }, + "streams": { + "items": { + "additionalProperties": true, + "properties": { + "data_stream": { + "additionalProperties": true, + "properties": { + "dataset": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset" + ], + "type": "object" + }, + "id": { + "type": "string" + } + }, + "required": [ + "data_stream" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "type": { + "type": "string" + }, + "use_output": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "revision", + "type", + "data_stream", + "use_output", + "package_policy_id" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "maxItems": 1, + "type": "array" + }, + "body": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "diff": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + }, + { + "additionalProperties": true, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "errors": { + "items": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + }, + "force": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "inputs": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "is_managed": { + "type": "boolean" + }, + "missingVars": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs" + ], + "type": "object" + } + ] + }, + "maxItems": 2, + "type": "array" + }, + "hasErrors": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "hasErrors" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Dry run a package policy upgrade", + "tags": [ + "Fleet package policies" + ] + } + }, + "/api/fleet/package_policies/{packagePolicyId}": { + "delete": { + "description": "Delete a package policy by ID.

[Required authorization] Route required privileges: fleet-agent-policies-all AND integrations-all.", + "operationId": "delete-fleet-package-policies-packagepolicyid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "packagePolicyId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "force", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Delete a package policy", + "tags": [ + "Fleet package policies" + ] + }, + "get": { + "description": "Get a package policy by ID.", + "operationId": "get-fleet-package-policies-packagepolicyid", + "parameters": [ + { + "in": "path", + "name": "packagePolicyId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "format", + "required": false, + "schema": { + "enum": [ + "simplified", + "legacy" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "404": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + }, + "description": "Not found." + } + }, + "summary": "Get a package policy", + "tags": [ + "Fleet package policies" + ] + }, + "put": { + "description": "Update a package policy by ID.", + "operationId": "put-fleet-package-policies-packagepolicyid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "packagePolicyId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "format", + "required": false, + "schema": { + "enum": [ + "simplified", + "legacy" + ], + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "force": { + "type": "boolean" + }, + "inputs": { + "items": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "version": { + "type": "string" + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 100, + "nullable": true, + "type": "array" + }, + "description": { + "description": "Policy description.", + "type": "string" + }, + "force": { + "description": "Force package policy creation even if the package is not verified, or if the agent policy is managed.", + "type": "boolean" + }, + "id": { + "description": "Policy unique identifier.", + "type": "string" + }, + "inputs": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object" + }, + "name": { + "description": "Unique name for the policy.", + "type": "string" + }, + "namespace": { + "description": "Policy namespace. When not specified, it inherits the agent policy namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "Deprecated. Use policy_ids instead.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "description": "IDs of the agent policies which that package policy will be added to.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "supports_agentless": { + "default": false, + "deprecated": true, + "description": "Indicates whether the package policy belongs to an agentless agent policy. Deprecated in favor of the Fleet agentless policies API.", + "nullable": true, + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "required": [ + "name", + "package" + ], + "type": "object" + } + ] + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "additional_datastreams_permissions": { + "description": "Additional datastream permissions, that will be added to the agent policy.", + "items": { + "type": "string" + }, + "maxItems": 1000, + "nullable": true, + "type": "array" + }, + "agents": { + "type": "number" + }, + "cloud_connector_id": { + "description": "ID of the cloud connector associated with this package policy.", + "nullable": true, + "type": "string" + }, + "cloud_connector_name": { + "description": "Transient field for cloud connector name during creation.", + "maxLength": 255, + "minLength": 1, + "nullable": true, + "type": "string" + }, + "created_at": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "description": { + "description": "Package policy description", + "type": "string" + }, + "elasticsearch": { + "additionalProperties": true, + "properties": { + "privileges": { + "additionalProperties": true, + "properties": { + "cluster": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "description": "Package policy unique identifier.", + "type": "string" + }, + "inputs": { + "anyOf": [ + { + "items": { + "additionalProperties": false, + "properties": { + "compiled_input": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "policy_template": { + "type": "string" + }, + "streams": { + "items": { + "additionalProperties": false, + "properties": { + "compiled_stream": {}, + "config": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + "data_stream": { + "additionalProperties": false, + "properties": { + "dataset": { + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "dynamic_dataset": { + "type": "boolean" + }, + "dynamic_namespace": { + "type": "boolean" + }, + "privileges": { + "additionalProperties": false, + "properties": { + "indices": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "dataset", + "type" + ], + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "keep_enabled": { + "type": "boolean" + }, + "release": { + "enum": [ + "ga", + "beta", + "experimental" + ], + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "enabled", + "data_stream", + "compiled_stream" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "type": { + "type": "string" + }, + "vars": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + } + }, + "required": [ + "type", + "enabled", + "streams", + "compiled_input" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that input. Defaults to `true` (enabled).", + "type": "boolean" + }, + "streams": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable or disable that stream. Defaults to `true` (enabled).", + "type": "boolean" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Input streams. Refer to the integration documentation to know which streams are available.", + "type": "object" + }, + "vars": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object" + } + }, + "type": "object" + }, + "description": "Package policy inputs. Refer to the integration documentation to know which inputs are available.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package policy inputs." + }, + "is_managed": { + "type": "boolean" + }, + "name": { + "description": "Unique name for the package policy.", + "type": "string" + }, + "namespace": { + "description": "The package policy namespace. Leave blank to inherit the agent policy's namespace.", + "type": "string" + }, + "output_id": { + "nullable": true, + "type": "string" + }, + "overrides": { + "additionalProperties": false, + "description": "Override settings that are defined in the package policy. The override option should be used only in unusual circumstances and not as a routine procedure.", + "nullable": true, + "properties": { + "inputs": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "package": { + "additionalProperties": false, + "properties": { + "experimental_data_stream_features": { + "items": { + "additionalProperties": false, + "properties": { + "data_stream": { + "type": "string" + }, + "features": { + "additionalProperties": false, + "properties": { + "doc_value_only_numeric": { + "type": "boolean" + }, + "doc_value_only_other": { + "type": "boolean" + }, + "synthetic_source": { + "type": "boolean" + }, + "tsdb": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "required": [ + "data_stream", + "features" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "fips_compatible": { + "type": "boolean" + }, + "name": { + "description": "Package name", + "type": "string" + }, + "requires_root": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "version": { + "description": "Package version", + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "policy_id": { + "deprecated": true, + "description": "ID of the agent policy which the package policy will be added to.", + "nullable": true, + "type": "string" + }, + "policy_ids": { + "items": { + "description": "IDs of the agent policies which that package policy will be added to.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + "revision": { + "description": "Package policy revision.", + "type": "number" + }, + "secret_references": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + }, + "spaceIds": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "supports_agentless": { + "default": false, + "description": "Indicates whether the package policy belongs to an agentless agent policy.", + "nullable": true, + "type": "boolean" + }, + "supports_cloud_connector": { + "default": false, + "description": "Indicates whether the package policy supports cloud connectors.", + "nullable": true, + "type": "boolean" + }, + "updated_at": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "vars": { + "anyOf": [ + { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "frozen": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "value" + ], + "type": "object" + }, + "description": "Package variable (see integration documentation for more information)", + "type": "object" + }, + { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + }, + { + "type": "number" + }, + { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + { + "items": { + "type": "number" + }, + "maxItems": 100, + "type": "array" + }, + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "isSecretRef": { + "type": "boolean" + } + }, + "required": [ + "id", + "isSecretRef" + ], + "type": "object" + } + ], + "nullable": true + }, + "description": "Input/stream level variable. Refer to the integration documentation for more information.", + "type": "object", + "x-oas-optional": true + } + ], + "description": "Package level variable." + }, + "version": { + "description": "Package policy ES version.", + "type": "string" + } + }, + "required": [ + "name", + "enabled", + "inputs", + "id", + "revision", + "updated_at", + "updated_by", + "created_at", + "created_by" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "403": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "Forbidden." + } + }, + "summary": "Update a package policy", + "tags": [ + "Fleet package policies" + ] + } + }, + "/api/fleet/proxies": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-settings-read.", + "operationId": "get-fleet-proxies", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "certificate": { + "nullable": true, + "type": "string" + }, + "certificate_authorities": { + "nullable": true, + "type": "string" + }, + "certificate_key": { + "nullable": true, + "type": "string" + }, + "id": { + "type": "string" + }, + "is_preconfigured": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_headers": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + }, + { + "type": "number" + } + ] + }, + "nullable": true, + "type": "object" + }, + "url": { + "type": "string" + } + }, + "required": [ + "id", + "url", + "name" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "page": { + "type": "number" + }, + "perPage": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "total", + "page", + "perPage" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get proxies", + "tags": [ + "Fleet proxies" + ] + }, + "post": { + "description": "[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "post-fleet-proxies", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "certificate": { + "nullable": true, + "type": "string" + }, + "certificate_authorities": { + "nullable": true, + "type": "string" + }, + "certificate_key": { + "nullable": true, + "type": "string" + }, + "id": { + "type": "string" + }, + "is_preconfigured": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_headers": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + }, + { + "type": "number" + } + ] + }, + "nullable": true, + "type": "object" + }, + "url": { + "type": "string" + } + }, + "required": [ + "url", + "name" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "certificate": { + "nullable": true, + "type": "string" + }, + "certificate_authorities": { + "nullable": true, + "type": "string" + }, + "certificate_key": { + "nullable": true, + "type": "string" + }, + "id": { + "type": "string" + }, + "is_preconfigured": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_headers": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + }, + { + "type": "number" + } + ] + }, + "nullable": true, + "type": "object" + }, + "url": { + "type": "string" + } + }, + "required": [ + "id", + "url", + "name" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Create a proxy", + "tags": [ + "Fleet proxies" + ] + } + }, + "/api/fleet/proxies/{itemId}": { + "delete": { + "description": "Delete a proxy by ID

[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "delete-fleet-proxies-itemid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "itemId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Delete a proxy", + "tags": [ + "Fleet proxies" + ] + }, + "get": { + "description": "Get a proxy by ID.

[Required authorization] Route required privileges: fleet-settings-read.", + "operationId": "get-fleet-proxies-itemid", + "parameters": [ + { + "in": "path", + "name": "itemId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "certificate": { + "nullable": true, + "type": "string" + }, + "certificate_authorities": { + "nullable": true, + "type": "string" + }, + "certificate_key": { + "nullable": true, + "type": "string" + }, + "id": { + "type": "string" + }, + "is_preconfigured": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_headers": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + }, + { + "type": "number" + } + ] + }, + "nullable": true, + "type": "object" + }, + "url": { + "type": "string" + } + }, + "required": [ + "id", + "url", + "name" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get a proxy", + "tags": [ + "Fleet proxies" + ] + }, + "put": { + "description": "Update a proxy by ID.

[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "put-fleet-proxies-itemid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "itemId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "certificate": { + "nullable": true, + "type": "string" + }, + "certificate_authorities": { + "nullable": true, + "type": "string" + }, + "certificate_key": { + "nullable": true, + "type": "string" + }, + "name": { + "type": "string" + }, + "proxy_headers": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + }, + { + "type": "number" + } + ] + }, + "nullable": true, + "type": "object" + }, + "url": { + "type": "string" + } + }, + "required": [ + "certificate_authorities", + "certificate", + "certificate_key" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "certificate": { + "nullable": true, + "type": "string" + }, + "certificate_authorities": { + "nullable": true, + "type": "string" + }, + "certificate_key": { + "nullable": true, + "type": "string" + }, + "id": { + "type": "string" + }, + "is_preconfigured": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "proxy_headers": { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + }, + { + "type": "number" + } + ] + }, + "nullable": true, + "type": "object" + }, + "url": { + "type": "string" + } + }, + "required": [ + "id", + "url", + "name" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Update a proxy", + "tags": [ + "Fleet proxies" + ] + } + }, + "/api/fleet/remote_synced_integrations/status": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-settings-read AND integrations-read.", + "operationId": "get-fleet-remote-synced-integrations-status", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "custom_assets": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "error": { + "type": "string" + }, + "is_deleted": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "package_name": { + "type": "string" + }, + "package_version": { + "type": "string" + }, + "sync_status": { + "enum": [ + "completed", + "synchronizing", + "failed", + "warning" + ], + "type": "string" + }, + "type": { + "type": "string" + }, + "warning": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "title" + ], + "type": "object" + } + }, + "required": [ + "type", + "name", + "package_name", + "package_version", + "sync_status" + ], + "type": "object" + }, + "type": "object" + }, + "error": { + "type": "string" + }, + "integrations": { + "items": { + "additionalProperties": false, + "properties": { + "error": { + "type": "string" + }, + "id": { + "type": "string" + }, + "install_status": { + "additionalProperties": false, + "properties": { + "main": { + "type": "string" + }, + "remote": { + "type": "string" + } + }, + "required": [ + "main" + ], + "type": "object" + }, + "package_name": { + "type": "string" + }, + "package_version": { + "type": "string" + }, + "sync_status": { + "enum": [ + "completed", + "synchronizing", + "failed", + "warning" + ], + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "warning": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "title" + ], + "type": "object" + } + }, + "required": [ + "sync_status", + "install_status" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "warning": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "title" + ], + "type": "object" + } + }, + "required": [ + "integrations" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get remote synced integrations status", + "tags": [ + "Fleet remote synced integrations" + ], + "x-state": "Generally available; added in 9.1.0" + } + }, + "/api/fleet/remote_synced_integrations/{outputId}/remote_status": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-settings-read AND integrations-read.", + "operationId": "get-fleet-remote-synced-integrations-outputid-remote-status", + "parameters": [ + { + "in": "path", + "name": "outputId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "custom_assets": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "error": { + "type": "string" + }, + "is_deleted": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "package_name": { + "type": "string" + }, + "package_version": { + "type": "string" + }, + "sync_status": { + "enum": [ + "completed", + "synchronizing", + "failed", + "warning" + ], + "type": "string" + }, + "type": { + "type": "string" + }, + "warning": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "title" + ], + "type": "object" + } + }, + "required": [ + "type", + "name", + "package_name", + "package_version", + "sync_status" + ], + "type": "object" + }, + "type": "object" + }, + "error": { + "type": "string" + }, + "integrations": { + "items": { + "additionalProperties": false, + "properties": { + "error": { + "type": "string" + }, + "id": { + "type": "string" + }, + "install_status": { + "additionalProperties": false, + "properties": { + "main": { + "type": "string" + }, + "remote": { + "type": "string" + } + }, + "required": [ + "main" + ], + "type": "object" + }, + "package_name": { + "type": "string" + }, + "package_version": { + "type": "string" + }, + "sync_status": { + "enum": [ + "completed", + "synchronizing", + "failed", + "warning" + ], + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "warning": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "title" + ], + "type": "object" + } + }, + "required": [ + "sync_status", + "install_status" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "warning": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "title" + ], + "type": "object" + } + }, + "required": [ + "integrations" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get remote synced integrations status by outputId", + "tags": [ + "Fleet remote synced integrations" + ], + "x-state": "Generally available; added in 9.1.0" + } + }, + "/api/fleet/service_tokens": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "post-fleet-service-tokens", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "nullable": true, + "properties": { + "remote": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Create a service token", + "tags": [ + "Fleet service tokens" + ] + } + }, + "/api/fleet/settings": { + "get": { + "description": "[Required authorization] Route required privileges: fleet-settings-read.", + "operationId": "get-fleet-settings", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "action_secret_storage_requirements_met": { + "type": "boolean" + }, + "delete_unenrolled_agents": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + } + }, + "required": [ + "enabled", + "is_preconfigured" + ], + "type": "object" + }, + "has_seen_add_data_notice": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "ilm_migration_status": { + "additionalProperties": false, + "properties": { + "logs": { + "enum": [ + "success" + ], + "nullable": true, + "type": "string" + }, + "metrics": { + "enum": [ + "success" + ], + "nullable": true, + "type": "string" + }, + "synthetics": { + "enum": [ + "success" + ], + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "integration_knowledge_enabled": { + "type": "boolean" + }, + "output_secret_storage_requirements_met": { + "type": "boolean" + }, + "preconfigured_fields": { + "items": { + "enum": [ + "fleet_server_hosts" + ], + "type": "string" + }, + "maxItems": 1, + "type": "array" + }, + "prerelease_integrations_enabled": { + "type": "boolean" + }, + "secret_storage_requirements_met": { + "type": "boolean" + }, + "ssl_secret_storage_requirements_met": { + "type": "boolean" + }, + "use_space_awareness_migration_started_at": { + "nullable": true, + "type": "string" + }, + "use_space_awareness_migration_status": { + "enum": [ + "pending", + "success", + "error" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "404": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + }, + "description": "Not found." + } + }, + "summary": "Get settings", + "tags": [ + "Fleet internals" + ] + }, + "put": { + "description": "[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "put-fleet-settings", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "additional_yaml_config": { + "deprecated": true, + "type": "string" + }, + "delete_unenrolled_agents": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + } + }, + "required": [ + "enabled", + "is_preconfigured" + ], + "type": "object" + }, + "has_seen_add_data_notice": { + "deprecated": true, + "type": "boolean" + }, + "integration_knowledge_enabled": { + "type": "boolean" + }, + "kibana_ca_sha256": { + "deprecated": true, + "type": "string" + }, + "kibana_urls": { + "deprecated": true, + "items": { + "format": "uri", + "type": "string" + }, + "maxItems": 10, + "type": "array" + }, + "prerelease_integrations_enabled": { + "type": "boolean" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "action_secret_storage_requirements_met": { + "type": "boolean" + }, + "delete_unenrolled_agents": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + } + }, + "required": [ + "enabled", + "is_preconfigured" + ], + "type": "object" + }, + "has_seen_add_data_notice": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "ilm_migration_status": { + "additionalProperties": false, + "properties": { + "logs": { + "enum": [ + "success" + ], + "nullable": true, + "type": "string" + }, + "metrics": { + "enum": [ + "success" + ], + "nullable": true, + "type": "string" + }, + "synthetics": { + "enum": [ + "success" + ], + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, + "integration_knowledge_enabled": { + "type": "boolean" + }, + "output_secret_storage_requirements_met": { + "type": "boolean" + }, + "preconfigured_fields": { + "items": { + "enum": [ + "fleet_server_hosts" + ], + "type": "string" + }, + "maxItems": 1, + "type": "array" + }, + "prerelease_integrations_enabled": { + "type": "boolean" + }, + "secret_storage_requirements_met": { + "type": "boolean" + }, + "ssl_secret_storage_requirements_met": { + "type": "boolean" + }, + "use_space_awareness_migration_started_at": { + "nullable": true, + "type": "string" + }, + "use_space_awareness_migration_status": { + "enum": [ + "pending", + "success", + "error" + ], + "type": "string" + }, + "version": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "404": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + }, + "description": "Not found." + } + }, + "summary": "Update settings", + "tags": [ + "Fleet internals" + ] + } + }, + "/api/fleet/setup": { + "post": { + "description": "[Required authorization] Route required privileges: fleet-agents-read OR fleet-agent-policies-read OR fleet-settings-read OR fleet-setup.", + "operationId": "post-fleet-setup", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "A summary of the result of Fleet's `setup` lifecycle. If `isInitialized` is true, Fleet is ready to accept agent enrollment. `nonFatalErrors` may include useful insight into non-blocking issues with Fleet setup.", + "properties": { + "isInitialized": { + "type": "boolean" + }, + "nonFatalErrors": { + "items": { + "additionalProperties": false, + "properties": { + "message": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "message" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + } + }, + "required": [ + "isInitialized", + "nonFatalErrors" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + }, + "500": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Internal Server Error", + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + }, + "description": "An internal server error occurred." + } + }, + "summary": "Initiate Fleet setup", + "tags": [ + "Fleet internals" + ] + } + }, + "/api/fleet/space_settings": { + "get": { + "operationId": "get-fleet-space-settings", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "allowed_namespace_prefixes": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "managed_by": { + "type": "string" + } + }, + "required": [ + "allowed_namespace_prefixes" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + } + }, + "summary": "Get space settings", + "tags": [], + "x-state": "Generally available; added in 9.1.0" + }, + "put": { + "description": "[Required authorization] Route required privileges: fleet-settings-all.", + "operationId": "put-fleet-space-settings", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "allowed_namespace_prefixes": { + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "allowed_namespace_prefixes": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "managed_by": { + "type": "string" + } + }, + "required": [ + "allowed_namespace_prefixes" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + } + }, + "summary": "Create space settings", + "tags": [], + "x-state": "Generally available; added in 9.1.0" + } + }, + "/api/fleet/uninstall_tokens": { + "get": { + "description": "List the metadata for the latest uninstall tokens per agent policy.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "get-fleet-uninstall-tokens", + "parameters": [ + { + "description": "Partial match filtering for policy IDs", + "in": "query", + "name": "policyId", + "required": false, + "schema": { + "maxLength": 50, + "type": "string" + } + }, + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "maxLength": 50, + "type": "string" + } + }, + { + "description": "The number of items to return", + "in": "query", + "name": "perPage", + "required": false, + "schema": { + "minimum": 5, + "type": "number" + } + }, + { + "in": "query", + "name": "page", + "required": false, + "schema": { + "minimum": 1, + "type": "number" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "items": { + "items": { + "additionalProperties": false, + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "namespaces": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "policy_id": { + "type": "string" + }, + "policy_name": { + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "policy_id", + "created_at" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "page": { + "type": "number" + }, + "perPage": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "items", + "total", + "page", + "perPage" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get metadata for latest uninstall tokens", + "tags": [ + "Fleet uninstall tokens" + ] + } + }, + "/api/fleet/uninstall_tokens/{uninstallTokenId}": { + "get": { + "description": "Get one decrypted uninstall token by its ID.

[Required authorization] Route required privileges: fleet-agents-all.", + "operationId": "get-fleet-uninstall-tokens-uninstalltokenid", + "parameters": [ + { + "in": "path", + "name": "uninstallTokenId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "item": { + "additionalProperties": false, + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "namespaces": { + "items": { + "type": "string" + }, + "maxItems": 100, + "type": "array" + }, + "policy_id": { + "type": "string" + }, + "policy_name": { + "nullable": true, + "type": "string" + }, + "token": { + "type": "string" + } + }, + "required": [ + "id", + "policy_id", + "created_at", + "token" + ], + "type": "object" + } + }, + "required": [ + "item" + ], + "type": "object" + } + } + }, + "description": "OK: A successful request." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Generic Error", + "properties": { + "attributes": {}, + "error": { + "type": "string" + }, + "errorType": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "type": "number" + } + }, + "required": [ + "message", + "attributes" + ], + "type": "object" + } + } + }, + "description": "A bad request." + } + }, + "summary": "Get a decrypted uninstall token", + "tags": [ + "Fleet uninstall tokens" + ] + } + }, + "/api/maintenance_window": { + "post": { + "description": "[Required authorization] Route required privileges: write-maintenance-window.", + "operationId": "post-maintenance-window", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Whether the current maintenance window is enabled. Disabled maintenance windows do not suppress notifications.", + "type": "boolean" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "custom": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "The duration of the schedule. It allows values in `` format. `` is one of `d`, `h`, `m`, or `s` for hours, minutes, seconds. For example: `1d`, `5h`, `30m`, `5000s`.", + "type": "string" + }, + "recurring": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end date of a recurring schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-04-01T00:00:00.000Z`.", + "type": "string" + }, + "every": { + "description": "The interval and frequency of a recurring schedule. It allows values in `` format. `` is one of `d`, `w`, `M`, or `y` for days, weeks, months, years. For example: `15d`, `2w`, `3m`, `1y`.", + "type": "string" + }, + "occurrences": { + "description": "The total number of recurrences of the schedule.", + "minimum": 1, + "type": "number" + }, + "onMonth": { + "description": "The specific months for a recurring schedule. Valid values are 1-12.", + "items": { + "maximum": 12, + "minimum": 1, + "type": "number" + }, + "minItems": 1, + "type": "array" + }, + "onMonthDay": { + "description": "The specific days of the month for a recurring schedule. Valid values are 1-31.", + "items": { + "maximum": 31, + "minimum": 1, + "type": "number" + }, + "minItems": 1, + "type": "array" + }, + "onWeekDay": { + "description": "The specific days of the week (`[MO,TU,WE,TH,FR,SA,SU]`) or nth day of month (`[+1MO, -3FR, +2WE, -4SA, -5SU]`) for a recurring schedule.", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "start": { + "description": "The start date and time of the schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-03-12T12:00:00.000Z`.", + "type": "string" + }, + "timezone": { + "description": "The timezone of the schedule. The default timezone is UTC.", + "type": "string" + } + }, + "required": [ + "start", + "duration" + ], + "type": "object" + } + }, + "required": [ + "custom" + ], + "type": "object" + }, + "scope": { + "additionalProperties": false, + "properties": { + "alerting": { + "additionalProperties": false, + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "kql": { + "description": "A filter written in Kibana Query Language (KQL). Only alerts matching this query will be supressed by the maintenance window.", + "type": "string" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "required": [ + "alerting" + ], + "type": "object" + }, + "title": { + "description": "The name of the maintenance window. While this name does not have to be unique, a distinctive name can help you identify a specific maintenance window.", + "type": "string" + } + }, + "required": [ + "title", + "schedule" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "created_at": { + "description": "The date and time when the maintenance window was created.", + "type": "string" + }, + "created_by": { + "description": "The identifier for the user that created the maintenance window.", + "nullable": true, + "type": "string" + }, + "enabled": { + "description": "Whether the current maintenance window is enabled. Disabled maintenance windows do not suppress notifications.", + "type": "boolean" + }, + "id": { + "description": "The identifier for the maintenance window.", + "type": "string" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "custom": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "The duration of the schedule. It allows values in `` format. `` is one of `d`, `h`, `m`, or `s` for hours, minutes, seconds. For example: `1d`, `5h`, `30m`, `5000s`.", + "type": "string" + }, + "recurring": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end date of a recurring schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-04-01T00:00:00.000Z`.", + "type": "string" + }, + "every": { + "description": "The interval and frequency of a recurring schedule. It allows values in `` format. `` is one of `d`, `w`, `M`, or `y` for days, weeks, months, years. For example: `15d`, `2w`, `3m`, `1y`.", + "type": "string" + }, + "occurrences": { + "description": "The total number of recurrences of the schedule.", + "type": "number" + }, + "onMonth": { + "description": "The specific months for a recurring schedule. Valid values are 1-12.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onMonthDay": { + "description": "The specific days of the month for a recurring schedule. Valid values are 1-31.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onWeekDay": { + "description": "The specific days of the week (`[MO,TU,WE,TH,FR,SA,SU]`) or nth day of month (`[+1MO, -3FR, +2WE, -4SA, -5SU]`) for a recurring schedule.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "start": { + "description": "The start date and time of the schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-03-12T12:00:00.000Z`.", + "type": "string" + }, + "timezone": { + "description": "The timezone of the schedule. The default timezone is UTC.", + "type": "string" + } + }, + "required": [ + "start", + "duration" + ], + "type": "object" + } + }, + "required": [ + "custom" + ], + "type": "object" + }, + "scope": { + "additionalProperties": false, + "properties": { + "alerting": { + "additionalProperties": false, + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "required": [ + "alerting" + ], + "type": "object" + }, + "status": { + "description": "The current status of the maintenance window.", + "enum": [ + "running", + "upcoming", + "finished", + "archived", + "disabled" + ], + "type": "string" + }, + "title": { + "description": "The name of the maintenance window.", + "type": "string" + }, + "updated_at": { + "description": "The date and time when the maintenance window was last updated.", + "type": "string" + }, + "updated_by": { + "description": "The identifier for the user that last updated this maintenance window.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "title", + "enabled", + "created_by", + "updated_by", + "created_at", + "updated_at", + "status", + "schedule" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + } + }, + "summary": "Create a maintenance window.", + "tags": [ + "maintenance-window" + ], + "x-state": "Generally available; added in 9.1.0" + } + }, + "/api/maintenance_window/_find": { + "get": { + "description": "[Required authorization] Route required privileges: read-maintenance-window.", + "operationId": "get-maintenance-window-find", + "parameters": [ + { + "description": "The title of the maintenance window.", + "in": "query", + "name": "title", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "The user who created the maintenance window.", + "in": "query", + "name": "created_by", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "The status of the maintenance window. It can be \"running\", \"upcoming\", \"finished\", \"archived\", or \"disabled\".", + "in": "query", + "name": "status", + "required": false, + "schema": { + "anyOf": [ + { + "enum": [ + "running", + "finished", + "upcoming", + "archived", + "disabled" + ], + "type": "string" + }, + { + "items": { + "enum": [ + "running", + "finished", + "upcoming", + "archived", + "disabled" + ], + "type": "string" + }, + "type": "array" + } + ] + } + }, + { + "description": "The page number to return.", + "in": "query", + "name": "page", + "required": false, + "schema": { + "default": 1, + "maximum": 100, + "minimum": 1, + "type": "number" + } + }, + { + "description": "The number of maintenance windows to return per page.", + "in": "query", + "name": "per_page", + "required": false, + "schema": { + "default": 10, + "maximum": 100, + "minimum": 1, + "type": "number" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "maintenanceWindows": { + "items": { + "additionalProperties": false, + "properties": { + "created_at": { + "description": "The date and time when the maintenance window was created.", + "type": "string" + }, + "created_by": { + "description": "The identifier for the user that created the maintenance window.", + "nullable": true, + "type": "string" + }, + "enabled": { + "description": "Whether the current maintenance window is enabled. Disabled maintenance windows do not suppress notifications.", + "type": "boolean" + }, + "id": { + "description": "The identifier for the maintenance window.", + "type": "string" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "custom": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "The duration of the schedule. It allows values in `` format. `` is one of `d`, `h`, `m`, or `s` for hours, minutes, seconds. For example: `1d`, `5h`, `30m`, `5000s`.", + "type": "string" + }, + "recurring": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end date of a recurring schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-04-01T00:00:00.000Z`.", + "type": "string" + }, + "every": { + "description": "The interval and frequency of a recurring schedule. It allows values in `` format. `` is one of `d`, `w`, `M`, or `y` for days, weeks, months, years. For example: `15d`, `2w`, `3m`, `1y`.", + "type": "string" + }, + "occurrences": { + "description": "The total number of recurrences of the schedule.", + "type": "number" + }, + "onMonth": { + "description": "The specific months for a recurring schedule. Valid values are 1-12.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onMonthDay": { + "description": "The specific days of the month for a recurring schedule. Valid values are 1-31.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onWeekDay": { + "description": "The specific days of the week (`[MO,TU,WE,TH,FR,SA,SU]`) or nth day of month (`[+1MO, -3FR, +2WE, -4SA, -5SU]`) for a recurring schedule.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "start": { + "description": "The start date and time of the schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-03-12T12:00:00.000Z`.", + "type": "string" + }, + "timezone": { + "description": "The timezone of the schedule. The default timezone is UTC.", + "type": "string" + } + }, + "required": [ + "start", + "duration" + ], + "type": "object" + } + }, + "required": [ + "custom" + ], + "type": "object" + }, + "scope": { + "additionalProperties": false, + "properties": { + "alerting": { + "additionalProperties": false, + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "required": [ + "alerting" + ], + "type": "object" + }, + "status": { + "description": "The current status of the maintenance window.", + "enum": [ + "running", + "upcoming", + "finished", + "archived", + "disabled" + ], + "type": "string" + }, + "title": { + "description": "The name of the maintenance window.", + "type": "string" + }, + "updated_at": { + "description": "The date and time when the maintenance window was last updated.", + "type": "string" + }, + "updated_by": { + "description": "The identifier for the user that last updated this maintenance window.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "title", + "enabled", + "created_by", + "updated_by", + "created_at", + "updated_at", + "status", + "schedule" + ], + "type": "object" + }, + "type": "array" + }, + "page": { + "type": "number" + }, + "per_page": { + "type": "number" + }, + "total": { + "type": "number" + } + }, + "required": [ + "page", + "per_page", + "total", + "maintenanceWindows" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + } + }, + "summary": "Search for a maintenance window.", + "tags": [ + "maintenance-window" + ], + "x-state": "Generally available; added in 9.2.0" + } + }, + "/api/maintenance_window/{id}": { + "delete": { + "description": "[Required authorization] Route required privileges: write-maintenance-window.", + "operationId": "delete-maintenance-window-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the maintenance window to be deleted.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a maintenance window with the given ID does not exist." + } + }, + "summary": "Delete a maintenance window.", + "tags": [ + "maintenance-window" + ], + "x-state": "Generally available; added in 9.1.0" + }, + "get": { + "description": "[Required authorization] Route required privileges: read-maintenance-window.", + "operationId": "get-maintenance-window-id", + "parameters": [ + { + "description": "The identifier for the maintenance window.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "created_at": { + "description": "The date and time when the maintenance window was created.", + "type": "string" + }, + "created_by": { + "description": "The identifier for the user that created the maintenance window.", + "nullable": true, + "type": "string" + }, + "enabled": { + "description": "Whether the current maintenance window is enabled. Disabled maintenance windows do not suppress notifications.", + "type": "boolean" + }, + "id": { + "description": "The identifier for the maintenance window.", + "type": "string" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "custom": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "The duration of the schedule. It allows values in `` format. `` is one of `d`, `h`, `m`, or `s` for hours, minutes, seconds. For example: `1d`, `5h`, `30m`, `5000s`.", + "type": "string" + }, + "recurring": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end date of a recurring schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-04-01T00:00:00.000Z`.", + "type": "string" + }, + "every": { + "description": "The interval and frequency of a recurring schedule. It allows values in `` format. `` is one of `d`, `w`, `M`, or `y` for days, weeks, months, years. For example: `15d`, `2w`, `3m`, `1y`.", + "type": "string" + }, + "occurrences": { + "description": "The total number of recurrences of the schedule.", + "type": "number" + }, + "onMonth": { + "description": "The specific months for a recurring schedule. Valid values are 1-12.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onMonthDay": { + "description": "The specific days of the month for a recurring schedule. Valid values are 1-31.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onWeekDay": { + "description": "The specific days of the week (`[MO,TU,WE,TH,FR,SA,SU]`) or nth day of month (`[+1MO, -3FR, +2WE, -4SA, -5SU]`) for a recurring schedule.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "start": { + "description": "The start date and time of the schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-03-12T12:00:00.000Z`.", + "type": "string" + }, + "timezone": { + "description": "The timezone of the schedule. The default timezone is UTC.", + "type": "string" + } + }, + "required": [ + "start", + "duration" + ], + "type": "object" + } + }, + "required": [ + "custom" + ], + "type": "object" + }, + "scope": { + "additionalProperties": false, + "properties": { + "alerting": { + "additionalProperties": false, + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "required": [ + "alerting" + ], + "type": "object" + }, + "status": { + "description": "The current status of the maintenance window.", + "enum": [ + "running", + "upcoming", + "finished", + "archived", + "disabled" + ], + "type": "string" + }, + "title": { + "description": "The name of the maintenance window.", + "type": "string" + }, + "updated_at": { + "description": "The date and time when the maintenance window was last updated.", + "type": "string" + }, + "updated_by": { + "description": "The identifier for the user that last updated this maintenance window.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "title", + "enabled", + "created_by", + "updated_by", + "created_at", + "updated_at", + "status", + "schedule" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a maintenance window with the given ID does not exist." + } + }, + "summary": "Get maintenance window details.", + "tags": [ + "maintenance-window" + ], + "x-state": "Generally available; added in 9.1.0" + }, + "patch": { + "description": "[Required authorization] Route required privileges: write-maintenance-window.", + "operationId": "patch-maintenance-window-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Whether the current maintenance window is enabled. Disabled maintenance windows do not suppress notifications.", + "type": "boolean" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "custom": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "The duration of the schedule. It allows values in `` format. `` is one of `d`, `h`, `m`, or `s` for hours, minutes, seconds. For example: `1d`, `5h`, `30m`, `5000s`.", + "type": "string" + }, + "recurring": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end date of a recurring schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-04-01T00:00:00.000Z`.", + "type": "string" + }, + "every": { + "description": "The interval and frequency of a recurring schedule. It allows values in `` format. `` is one of `d`, `w`, `M`, or `y` for days, weeks, months, years. For example: `15d`, `2w`, `3m`, `1y`.", + "type": "string" + }, + "occurrences": { + "description": "The total number of recurrences of the schedule.", + "minimum": 1, + "type": "number" + }, + "onMonth": { + "description": "The specific months for a recurring schedule. Valid values are 1-12.", + "items": { + "maximum": 12, + "minimum": 1, + "type": "number" + }, + "minItems": 1, + "type": "array" + }, + "onMonthDay": { + "description": "The specific days of the month for a recurring schedule. Valid values are 1-31.", + "items": { + "maximum": 31, + "minimum": 1, + "type": "number" + }, + "minItems": 1, + "type": "array" + }, + "onWeekDay": { + "description": "The specific days of the week (`[MO,TU,WE,TH,FR,SA,SU]`) or nth day of month (`[+1MO, -3FR, +2WE, -4SA, -5SU]`) for a recurring schedule.", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "start": { + "description": "The start date and time of the schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-03-12T12:00:00.000Z`.", + "type": "string" + }, + "timezone": { + "description": "The timezone of the schedule. The default timezone is UTC.", + "type": "string" + } + }, + "required": [ + "start", + "duration" + ], + "type": "object" + } + }, + "required": [ + "custom" + ], + "type": "object" + }, + "scope": { + "additionalProperties": false, + "properties": { + "alerting": { + "additionalProperties": false, + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "kql": { + "description": "A filter written in Kibana Query Language (KQL). Only alerts matching this query will be supressed by the maintenance window.", + "type": "string" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "required": [ + "alerting" + ], + "type": "object" + }, + "title": { + "description": "The name of the maintenance window. While this name does not have to be unique, a distinctive name can help you identify a specific maintenance window.", + "type": "string" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "created_at": { + "description": "The date and time when the maintenance window was created.", + "type": "string" + }, + "created_by": { + "description": "The identifier for the user that created the maintenance window.", + "nullable": true, + "type": "string" + }, + "enabled": { + "description": "Whether the current maintenance window is enabled. Disabled maintenance windows do not suppress notifications.", + "type": "boolean" + }, + "id": { + "description": "The identifier for the maintenance window.", + "type": "string" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "custom": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "The duration of the schedule. It allows values in `` format. `` is one of `d`, `h`, `m`, or `s` for hours, minutes, seconds. For example: `1d`, `5h`, `30m`, `5000s`.", + "type": "string" + }, + "recurring": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end date of a recurring schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-04-01T00:00:00.000Z`.", + "type": "string" + }, + "every": { + "description": "The interval and frequency of a recurring schedule. It allows values in `` format. `` is one of `d`, `w`, `M`, or `y` for days, weeks, months, years. For example: `15d`, `2w`, `3m`, `1y`.", + "type": "string" + }, + "occurrences": { + "description": "The total number of recurrences of the schedule.", + "type": "number" + }, + "onMonth": { + "description": "The specific months for a recurring schedule. Valid values are 1-12.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onMonthDay": { + "description": "The specific days of the month for a recurring schedule. Valid values are 1-31.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onWeekDay": { + "description": "The specific days of the week (`[MO,TU,WE,TH,FR,SA,SU]`) or nth day of month (`[+1MO, -3FR, +2WE, -4SA, -5SU]`) for a recurring schedule.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "start": { + "description": "The start date and time of the schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-03-12T12:00:00.000Z`.", + "type": "string" + }, + "timezone": { + "description": "The timezone of the schedule. The default timezone is UTC.", + "type": "string" + } + }, + "required": [ + "start", + "duration" + ], + "type": "object" + } + }, + "required": [ + "custom" + ], + "type": "object" + }, + "scope": { + "additionalProperties": false, + "properties": { + "alerting": { + "additionalProperties": false, + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "required": [ + "alerting" + ], + "type": "object" + }, + "status": { + "description": "The current status of the maintenance window.", + "enum": [ + "running", + "upcoming", + "finished", + "archived", + "disabled" + ], + "type": "string" + }, + "title": { + "description": "The name of the maintenance window.", + "type": "string" + }, + "updated_at": { + "description": "The date and time when the maintenance window was last updated.", + "type": "string" + }, + "updated_by": { + "description": "The identifier for the user that last updated this maintenance window.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "title", + "enabled", + "created_by", + "updated_by", + "created_at", + "updated_at", + "status", + "schedule" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a maintenance window with the given ID does not exist." + }, + "409": { + "description": "Indicates that the maintenance window has already been updated by another user." + } + }, + "summary": "Update a maintenance window.", + "tags": [ + "maintenance-window" + ], + "x-state": "Generally available; added in 9.1.0" + } + }, + "/api/maintenance_window/{id}/_archive": { + "post": { + "description": "[Required authorization] Route required privileges: write-maintenance-window.", + "operationId": "post-maintenance-window-id-archive", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the maintenance window to be archived.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "created_at": { + "description": "The date and time when the maintenance window was created.", + "type": "string" + }, + "created_by": { + "description": "The identifier for the user that created the maintenance window.", + "nullable": true, + "type": "string" + }, + "enabled": { + "description": "Whether the current maintenance window is enabled. Disabled maintenance windows do not suppress notifications.", + "type": "boolean" + }, + "id": { + "description": "The identifier for the maintenance window.", + "type": "string" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "custom": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "The duration of the schedule. It allows values in `` format. `` is one of `d`, `h`, `m`, or `s` for hours, minutes, seconds. For example: `1d`, `5h`, `30m`, `5000s`.", + "type": "string" + }, + "recurring": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end date of a recurring schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-04-01T00:00:00.000Z`.", + "type": "string" + }, + "every": { + "description": "The interval and frequency of a recurring schedule. It allows values in `` format. `` is one of `d`, `w`, `M`, or `y` for days, weeks, months, years. For example: `15d`, `2w`, `3m`, `1y`.", + "type": "string" + }, + "occurrences": { + "description": "The total number of recurrences of the schedule.", + "type": "number" + }, + "onMonth": { + "description": "The specific months for a recurring schedule. Valid values are 1-12.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onMonthDay": { + "description": "The specific days of the month for a recurring schedule. Valid values are 1-31.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onWeekDay": { + "description": "The specific days of the week (`[MO,TU,WE,TH,FR,SA,SU]`) or nth day of month (`[+1MO, -3FR, +2WE, -4SA, -5SU]`) for a recurring schedule.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "start": { + "description": "The start date and time of the schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-03-12T12:00:00.000Z`.", + "type": "string" + }, + "timezone": { + "description": "The timezone of the schedule. The default timezone is UTC.", + "type": "string" + } + }, + "required": [ + "start", + "duration" + ], + "type": "object" + } + }, + "required": [ + "custom" + ], + "type": "object" + }, + "scope": { + "additionalProperties": false, + "properties": { + "alerting": { + "additionalProperties": false, + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "required": [ + "alerting" + ], + "type": "object" + }, + "status": { + "description": "The current status of the maintenance window.", + "enum": [ + "running", + "upcoming", + "finished", + "archived", + "disabled" + ], + "type": "string" + }, + "title": { + "description": "The name of the maintenance window.", + "type": "string" + }, + "updated_at": { + "description": "The date and time when the maintenance window was last updated.", + "type": "string" + }, + "updated_by": { + "description": "The identifier for the user that last updated this maintenance window.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "title", + "enabled", + "created_by", + "updated_by", + "created_at", + "updated_at", + "status", + "schedule" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a maintenance window with the given ID does not exist." + } + }, + "summary": "Archive a maintenance window.", + "tags": [ + "maintenance-window" + ], + "x-state": "Generally available; added in 9.1.0" + } + }, + "/api/maintenance_window/{id}/_unarchive": { + "post": { + "description": "[Required authorization] Route required privileges: write-maintenance-window.", + "operationId": "post-maintenance-window-id-unarchive", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The identifier for the maintenance window to be unarchived.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "created_at": { + "description": "The date and time when the maintenance window was created.", + "type": "string" + }, + "created_by": { + "description": "The identifier for the user that created the maintenance window.", + "nullable": true, + "type": "string" + }, + "enabled": { + "description": "Whether the current maintenance window is enabled. Disabled maintenance windows do not suppress notifications.", + "type": "boolean" + }, + "id": { + "description": "The identifier for the maintenance window.", + "type": "string" + }, + "schedule": { + "additionalProperties": false, + "properties": { + "custom": { + "additionalProperties": false, + "properties": { + "duration": { + "description": "The duration of the schedule. It allows values in `` format. `` is one of `d`, `h`, `m`, or `s` for hours, minutes, seconds. For example: `1d`, `5h`, `30m`, `5000s`.", + "type": "string" + }, + "recurring": { + "additionalProperties": false, + "properties": { + "end": { + "description": "The end date of a recurring schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-04-01T00:00:00.000Z`.", + "type": "string" + }, + "every": { + "description": "The interval and frequency of a recurring schedule. It allows values in `` format. `` is one of `d`, `w`, `M`, or `y` for days, weeks, months, years. For example: `15d`, `2w`, `3m`, `1y`.", + "type": "string" + }, + "occurrences": { + "description": "The total number of recurrences of the schedule.", + "type": "number" + }, + "onMonth": { + "description": "The specific months for a recurring schedule. Valid values are 1-12.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onMonthDay": { + "description": "The specific days of the month for a recurring schedule. Valid values are 1-31.", + "items": { + "type": "number" + }, + "type": "array" + }, + "onWeekDay": { + "description": "The specific days of the week (`[MO,TU,WE,TH,FR,SA,SU]`) or nth day of month (`[+1MO, -3FR, +2WE, -4SA, -5SU]`) for a recurring schedule.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "start": { + "description": "The start date and time of the schedule, provided in ISO 8601 format and set to the UTC timezone. For example: `2025-03-12T12:00:00.000Z`.", + "type": "string" + }, + "timezone": { + "description": "The timezone of the schedule. The default timezone is UTC.", + "type": "string" + } + }, + "required": [ + "start", + "duration" + ], + "type": "object" + } + }, + "required": [ + "custom" + ], + "type": "object" + }, + "scope": { + "additionalProperties": false, + "properties": { + "alerting": { + "additionalProperties": false, + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "kql": { + "description": "A filter written in Kibana Query Language (KQL).", + "type": "string" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "required": [ + "alerting" + ], + "type": "object" + }, + "status": { + "description": "The current status of the maintenance window.", + "enum": [ + "running", + "upcoming", + "finished", + "archived", + "disabled" + ], + "type": "string" + }, + "title": { + "description": "The name of the maintenance window.", + "type": "string" + }, + "updated_at": { + "description": "The date and time when the maintenance window was last updated.", + "type": "string" + }, + "updated_by": { + "description": "The identifier for the user that last updated this maintenance window.", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "title", + "enabled", + "created_by", + "updated_by", + "created_at", + "updated_at", + "status", + "schedule" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "description": "Indicates an invalid schema or parameters." + }, + "403": { + "description": "Indicates that this call is forbidden." + }, + "404": { + "description": "Indicates a maintenance window with the given ID does not exist." + } + }, + "summary": "Unarchive a maintenance window.", + "tags": [ + "maintenance-window" + ], + "x-state": "Generally available; added in 9.1.0" + } + }, + "/api/saved_objects/_export": { + "post": { + "description": "Retrieve sets of saved objects that you want to import into Kibana. You must include `type` or `objects` in the request body. The output of exporting saved objects must be treated as opaque. Tampering with exported data risks introducing unspecified errors and data loss.\n\nExported saved objects are not backwards compatible and cannot be imported into an older version of Kibana.\n\nNOTE: The `savedObjects.maxImportExportSize` configuration setting limits the number of saved objects which may be exported.", + "operationId": "post-saved-objects-export", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "exportSavedObjectsRequest": { + "summary": "Export a specific saved object.", + "value": { + "excludeExportDetails": true, + "includeReferencesDeep": false, + "objects": [ + { + "id": "de71f4f0-1902-11e9-919b-ffe5949a18d2", + "type": "map" + } + ] + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "excludeExportDetails": { + "default": false, + "description": "Do not add export details entry at the end of the stream.", + "type": "boolean" + }, + "hasReference": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "id" + ], + "type": "object" + }, + { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "id" + ], + "type": "object" + }, + "type": "array" + } + ] + }, + "includeReferencesDeep": { + "default": false, + "description": "Includes all of the referenced objects in the exported objects.", + "type": "boolean" + }, + "objects": { + "description": "A list of objects to export. NOTE: this optional parameter cannot be combined with the `types` option", + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "id" + ], + "type": "object" + }, + "maxItems": 10000, + "type": "array" + }, + "search": { + "description": "Search for documents to export using the Elasticsearch Simple Query String syntax.", + "type": "string" + }, + "type": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "description": "The saved object types to include in the export. Use `*` to export all the types. Valid options depend on enabled plugins, but may include `visualization`, `dashboard`, `search`, `index-pattern`, `tag`, `config`, `config-global`, `lens`, `map`, `event-annotation-group`, `query`, `url`, `action`, `alert`, `alerting_rule_template`, `apm-indices`, `cases-user-actions`, `cases`, `cases-comments`, `infrastructure-monitoring-log-view`, `ml-trained-model`, `osquery-saved-query`, `osquery-pack`, `osquery-pack-asset`." + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/x-ndjson": { + "examples": { + "exportSavedObjectsResponse": { + "summary": "The export objects API response contains a JSON record for each exported object.", + "value": { + "attributes": { + "description": "", + "layerListJSON": "[{\"id\":\"0hmz5\",\"alpha\":1,\"sourceDescriptor\":{\"type\":\"EMS_TMS\",\"isAutoSelect\":true,\"lightModeDefault\":\"road_map_desaturated\"},\"visible\":true,\"style\":{},\"type\":\"EMS_VECTOR_TILE\",\"minZoom\":0,\"maxZoom\":24},{\"id\":\"edh66\",\"label\":\"Total Requests by Destination\",\"minZoom\":0,\"maxZoom\":24,\"alpha\":0.5,\"sourceDescriptor\":{\"type\":\"EMS_FILE\",\"id\":\"world_countries\",\"tooltipProperties\":[\"name\",\"iso2\"]},\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"name\":\"__kbnjoin__count__673ff994-fc75-4c67-909b-69fcb0e1060e\",\"origin\":\"join\"},\"color\":\"Greys\",\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"STATIC\",\"options\":{\"size\":10}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}}},\"type\":\"GEOJSON_VECTOR\",\"joins\":[{\"leftField\":\"iso2\",\"right\":{\"type\":\"ES_TERM_SOURCE\",\"id\":\"673ff994-fc75-4c67-909b-69fcb0e1060e\",\"indexPatternTitle\":\"kibana_sample_data_logs\",\"term\":\"geo.dest\",\"indexPatternRefName\":\"layer_1_join_0_index_pattern\",\"metrics\":[{\"type\":\"count\",\"label\":\"web logs count\"}],\"applyGlobalQuery\":true}}]},{\"id\":\"gaxya\",\"label\":\"Actual Requests\",\"minZoom\":9,\"maxZoom\":24,\"alpha\":1,\"sourceDescriptor\":{\"id\":\"b7486535-171b-4d3b-bb2e-33c1a0a2854c\",\"type\":\"ES_SEARCH\",\"geoField\":\"geo.coordinates\",\"limit\":2048,\"filterByMapBounds\":true,\"tooltipProperties\":[\"clientip\",\"timestamp\",\"host\",\"request\",\"response\",\"machine.os\",\"agent\",\"bytes\"],\"indexPatternRefName\":\"layer_2_source_index_pattern\",\"applyGlobalQuery\":true,\"scalingType\":\"LIMIT\"},\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#2200ff\"}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#FFFFFF\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":2}},\"iconSize\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"name\":\"bytes\",\"origin\":\"source\"},\"minSize\":1,\"maxSize\":23,\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}}},\"type\":\"GEOJSON_VECTOR\"},{\"id\":\"tfi3f\",\"label\":\"Total Requests and Bytes\",\"minZoom\":0,\"maxZoom\":9,\"alpha\":1,\"sourceDescriptor\":{\"type\":\"ES_GEO_GRID\",\"resolution\":\"COARSE\",\"id\":\"8aaa65b5-a4e9-448b-9560-c98cb1c5ac5b\",\"geoField\":\"geo.coordinates\",\"requestType\":\"point\",\"metrics\":[{\"type\":\"count\",\"label\":\"web logs count\"},{\"type\":\"sum\",\"field\":\"bytes\"}],\"indexPatternRefName\":\"layer_3_source_index_pattern\",\"applyGlobalQuery\":true},\"visible\":true,\"style\":{\"type\":\"VECTOR\",\"properties\":{\"fillColor\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"name\":\"doc_count\",\"origin\":\"source\"},\"color\":\"Blues\",\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"lineColor\":{\"type\":\"STATIC\",\"options\":{\"color\":\"#cccccc\"}},\"lineWidth\":{\"type\":\"STATIC\",\"options\":{\"size\":1}},\"iconSize\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"name\":\"sum_of_bytes\",\"origin\":\"source\"},\"minSize\":7,\"maxSize\":25,\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"labelText\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"name\":\"doc_count\",\"origin\":\"source\"},\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"labelSize\":{\"type\":\"DYNAMIC\",\"options\":{\"field\":{\"name\":\"doc_count\",\"origin\":\"source\"},\"minSize\":12,\"maxSize\":24,\"fieldMetaOptions\":{\"isEnabled\":false,\"sigma\":3}}},\"symbolizeAs\":{\"options\":{\"value\":\"circle\"}},\"icon\":{\"type\":\"STATIC\",\"options\":{\"value\":\"marker\"}}}},\"type\":\"GEOJSON_VECTOR\"}]", + "mapStateJSON": "{\"zoom\":3.64,\"center\":{\"lon\":-88.92107,\"lat\":42.16337},\"timeFilters\":{\"from\":\"now-7d\",\"to\":\"now\"},\"refreshConfig\":{\"isPaused\":true,\"interval\":0},\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"settings\":{\"autoFitToDataBounds\":false}}", + "title": "[Logs] Total Requests and Bytes", + "uiStateJSON": "{\"isDarkMode\":false}" + }, + "coreMigrationVersion": "8.8.0", + "created_at": "2023-08-23T20:03:32.204Z", + "id": "de71f4f0-1902-11e9-919b-ffe5949a18d2", + "managed": false, + "references": [ + { + "id": "90943e30-9a47-11e8-b64d-95841ca0b247", + "name": "layer_1_join_0_index_pattern", + "type": "index-pattern" + }, + { + "id": "90943e30-9a47-11e8-b64d-95841ca0b247", + "name": "layer_2_source_index_pattern", + "type": "index-pattern" + }, + { + "id": "90943e30-9a47-11e8-b64d-95841ca0b247", + "name": "layer_3_source_index_pattern", + "type": "index-pattern" + } + ], + "type": "map", + "typeMigrationVersion": "8.4.0", + "updated_at": "2023-08-23T20:03:32.204Z", + "version": "WzEzLDFd" + } + } + }, + "schema": {} + } + }, + "description": "Indicates a successfull call." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Indicates an unsuccessful response.", + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "enum": [ + 400 + ], + "type": "integer" + } + }, + "required": [ + "error", + "message", + "statusCode" + ], + "type": "object" + } + } + }, + "description": "Bad request." + } + }, + "summary": "Export saved objects", + "tags": [ + "saved objects" + ] + } + }, + "/api/saved_objects/_import": { + "post": { + "description": "Create sets of Kibana saved objects from a file created by the export API. Saved objects can only be imported into the same version, a newer minor on the same major, or the next major. Tampering with exported data risks introducing unspecified errors and data loss.\n\nExported saved objects are not backwards compatible and cannot be imported into an older version of Kibana.", + "operationId": "post-saved-objects-import", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "Overwrites saved objects when they already exist. When used, potential conflict errors are automatically resolved by overwriting the destination object. NOTE: This option cannot be used with the `createNewCopies` option.", + "in": "query", + "name": "overwrite", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + }, + { + "description": "Creates copies of saved objects, regenerates each object ID, and resets the origin. When used, potential conflict errors are avoided. NOTE: This option cannot be used with the `overwrite` and `compatibilityMode` options.", + "in": "query", + "name": "createNewCopies", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + }, + { + "description": "Applies various adjustments to the saved objects that are being imported to maintain compatibility between different Kibana versions. Use this option only if you encounter issues with imported saved objects. NOTE: This option cannot be used with the `createNewCopies` option.", + "in": "query", + "name": "compatibilityMode", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "examples": { + "importObjectsRequest": { + "value": { + "file": "file.ndjson" + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "file": { + "description": "A file exported using the export API. Changing the contents of the exported file in any way before importing it can cause errors, crashes or data loss. NOTE: The `savedObjects.maxImportExportSize` configuration setting limits the number of saved objects which may be included in this file. Similarly, the `savedObjects.maxImportPayloadBytes` setting limits the overall size of the file that can be imported.", + "type": "object" + } + }, + "required": [ + "file" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "importObjectsResponse": { + "summary": "The import objects API response indicates a successful import and the objects are created. Since these objects are created as new copies, each entry in the successResults array includes a destinationId attribute.", + "value": { + "success": true, + "successCount": 1, + "successResults": [ + { + "destinationId": "82d2760c-468f-49cf-83aa-b9a35b6a8943", + "id": "90943e30-9a47-11e8-b64d-95841ca0b247", + "managed": false, + "meta": { + "icon": "indexPatternApp", + "title": "Kibana Sample Data Logs" + }, + "type": "index-pattern" + } + ] + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "errors": { + "description": "Indicates the import was unsuccessful and specifies the objects that failed to import.\n\nNOTE: One object may result in multiple errors, which requires separate steps to resolve. For instance, a `missing_references` error and conflict error.", + "items": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "type": "array" + }, + "success": { + "description": "Indicates when the import was successfully completed. When set to false, some objects may not have been created. For additional information, refer to the `errors` and `successResults` properties.", + "type": "boolean" + }, + "successCount": { + "description": "Indicates the number of successfully imported records.", + "type": "number" + }, + "successResults": { + "description": "Indicates the objects that are successfully imported, with any metadata if applicable.\n\nNOTE: Objects are created only when all resolvable errors are addressed, including conflicts and missing references. If objects are created as new copies, each entry in the `successResults` array includes a `destinationId` attribute.", + "items": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "success", + "successCount", + "errors", + "successResults" + ], + "type": "object" + } + } + }, + "description": "Indicates a successful call." + }, + "400": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "description": "Indicates an unsuccessful response.", + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "statusCode": { + "enum": [ + 400 + ], + "type": "integer" + } + }, + "required": [ + "error", + "message", + "statusCode" + ], + "type": "object" + } + } + }, + "description": "Bad request." + } + }, + "summary": "Import saved objects", + "tags": [ + "saved objects" + ], + "x-codeSamples": [ + { + "label": "Import with createNewCopies", + "lang": "cURL", + "source": "curl \\\n -X POST api/saved_objects/_import?createNewCopies=true\n -H \"kbn-xsrf: true\"\n --form file=@file.ndjson\n" + } + ] + } + }, + "/api/security/role": { + "get": { + "operationId": "get-security-role", + "parameters": [ + { + "description": "If `true` and the response contains any privileges that are associated with deprecated features, they are omitted in favor of details about the appropriate replacement feature privileges.", + "in": "query", + "name": "replaceDeprecatedPrivileges", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "Indicates a successful call." + } + }, + "summary": "Get all roles", + "tags": [ + "roles" + ] + } + }, + "/api/security/role/_query": { + "post": { + "operationId": "post-security-role-query", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "filters": { + "additionalProperties": false, + "properties": { + "showReservedRoles": { + "type": "boolean" + } + }, + "type": "object" + }, + "from": { + "type": "number" + }, + "query": { + "type": "string" + }, + "size": { + "type": "number" + }, + "sort": { + "additionalProperties": false, + "properties": { + "direction": { + "enum": [ + "asc", + "desc" + ], + "type": "string" + }, + "field": { + "type": "string" + } + }, + "required": [ + "field", + "direction" + ], + "type": "object" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Indicates a successful call." + } + }, + "summary": "Query roles", + "tags": [] + } + }, + "/api/security/role/{name}": { + "delete": { + "operationId": "delete-security-role-name", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + } + }, + "summary": "Delete a role", + "tags": [ + "roles" + ] + }, + "get": { + "operationId": "get-security-role-name", + "parameters": [ + { + "description": "The role name.", + "in": "path", + "name": "name", + "required": true, + "schema": { + "minLength": 1, + "type": "string" + } + }, + { + "description": "If `true` and the response contains any privileges that are associated with deprecated features, they are omitted in favor of details about the appropriate replacement feature privileges.", + "in": "query", + "name": "replaceDeprecatedPrivileges", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "Indicates a successful call." + } + }, + "summary": "Get a role", + "tags": [ + "roles" + ] + }, + "put": { + "description": "Create a new Kibana role or update the attributes of an existing role. Kibana roles are stored in the Elasticsearch native realm.", + "operationId": "put-security-role-name", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The role name.", + "in": "path", + "name": "name", + "required": true, + "schema": { + "maxLength": 1024, + "minLength": 1, + "type": "string" + } + }, + { + "description": "When true, a role is not overwritten if it already exists.", + "in": "query", + "name": "createOnly", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "description": { + "description": "A description for the role.", + "maxLength": 2048, + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "cluster": { + "items": { + "description": "Cluster privileges that define the cluster level actions that users can perform.", + "type": "string" + }, + "type": "array" + }, + "indices": { + "items": { + "additionalProperties": false, + "properties": { + "allow_restricted_indices": { + "description": "Restricted indices are a special category of indices that are used internally to store configuration data and should not be directly accessed. Only internal system roles should normally grant privileges over the restricted indices. Toggling this flag is very strongly discouraged because it could effectively grant unrestricted operations on critical data, making the entire system unstable or leaking sensitive information. If for administrative purposes you need to create a role with privileges covering restricted indices, however, you can set this property to true. In that case, the names field covers the restricted indices too.", + "type": "boolean" + }, + "field_security": { + "additionalProperties": { + "items": { + "description": "The document fields that the role members have read access to.", + "type": "string" + }, + "type": "array" + }, + "type": "object" + }, + "names": { + "items": { + "description": "The data streams, indices, and aliases to which the permissions in this entry apply. It supports wildcards (*).", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "privileges": { + "items": { + "description": "The index level privileges that the role members have for the data streams and indices.", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "query": { + "description": "A search query that defines the documents the role members have read access to. A document within the specified data streams and indices must match this query in order for it to be accessible by the role members.", + "type": "string" + } + }, + "required": [ + "names", + "privileges" + ], + "type": "object" + }, + "type": "array" + }, + "remote_cluster": { + "items": { + "additionalProperties": false, + "properties": { + "clusters": { + "items": { + "description": "A list of remote cluster aliases. It supports literal strings as well as wildcards and regular expressions.", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "privileges": { + "items": { + "description": "The cluster level privileges for the remote cluster. The allowed values are a subset of the cluster privileges.", + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "privileges", + "clusters" + ], + "type": "object" + }, + "type": "array" + }, + "remote_indices": { + "items": { + "additionalProperties": false, + "properties": { + "allow_restricted_indices": { + "description": "Restricted indices are a special category of indices that are used internally to store configuration data and should not be directly accessed. Only internal system roles should normally grant privileges over the restricted indices. Toggling this flag is very strongly discouraged because it could effectively grant unrestricted operations on critical data, making the entire system unstable or leaking sensitive information. If for administrative purposes you need to create a role with privileges covering restricted indices, however, you can set this property to true. In that case, the names field will cover the restricted indices too.", + "type": "boolean" + }, + "clusters": { + "items": { + "description": "A list of remote cluster aliases. It supports literal strings as well as wildcards and regular expressions.", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "field_security": { + "additionalProperties": { + "items": { + "description": "The document fields that the role members have read access to.", + "type": "string" + }, + "type": "array" + }, + "type": "object" + }, + "names": { + "items": { + "description": "A list of remote aliases, data streams, or indices to which the permissions apply. It supports wildcards (*).", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "privileges": { + "items": { + "description": "The index level privileges that role members have for the specified indices.", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "query": { + "description": "A search query that defines the documents the role members have read access to. A document within the specified data streams and indices must match this query in order for it to be accessible by the role members. ", + "type": "string" + } + }, + "required": [ + "clusters", + "names", + "privileges" + ], + "type": "object" + }, + "type": "array" + }, + "run_as": { + "items": { + "description": "A user name that the role member can impersonate.", + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "kibana": { + "items": { + "additionalProperties": false, + "properties": { + "base": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "items": { + "description": "A base privilege that grants applies to all spaces.", + "type": "string" + }, + "type": "array" + }, + { + "items": { + "description": "A base privilege that applies to specific spaces.", + "type": "string" + }, + "type": "array" + } + ] + }, + "feature": { + "additionalProperties": { + "items": { + "description": "The privileges that the role member has for the feature.", + "type": "string" + }, + "type": "array" + }, + "type": "object" + }, + "spaces": { + "anyOf": [ + { + "items": { + "enum": [ + "*" + ], + "type": "string" + }, + "maxItems": 1, + "minItems": 1, + "type": "array" + }, + { + "items": { + "description": "A space that the privilege applies to.", + "type": "string" + }, + "type": "array" + } + ], + "default": [ + "*" + ] + } + }, + "required": [ + "base" + ], + "type": "object" + }, + "type": "array" + }, + "metadata": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "elasticsearch" + ], + "type": "object" + } + } + } + }, + "responses": { + "204": { + "description": "Indicates a successful call." + } + }, + "summary": "Create or update a role", + "tags": [ + "roles" + ] + } + }, + "/api/security/roles": { + "post": { + "operationId": "post-security-roles", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "roles": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "description": { + "description": "A description for the role.", + "maxLength": 2048, + "type": "string" + }, + "elasticsearch": { + "additionalProperties": false, + "properties": { + "cluster": { + "items": { + "description": "Cluster privileges that define the cluster level actions that users can perform.", + "type": "string" + }, + "type": "array" + }, + "indices": { + "items": { + "additionalProperties": false, + "properties": { + "allow_restricted_indices": { + "description": "Restricted indices are a special category of indices that are used internally to store configuration data and should not be directly accessed. Only internal system roles should normally grant privileges over the restricted indices. Toggling this flag is very strongly discouraged because it could effectively grant unrestricted operations on critical data, making the entire system unstable or leaking sensitive information. If for administrative purposes you need to create a role with privileges covering restricted indices, however, you can set this property to true. In that case, the names field covers the restricted indices too.", + "type": "boolean" + }, + "field_security": { + "additionalProperties": { + "items": { + "description": "The document fields that the role members have read access to.", + "type": "string" + }, + "type": "array" + }, + "type": "object" + }, + "names": { + "items": { + "description": "The data streams, indices, and aliases to which the permissions in this entry apply. It supports wildcards (*).", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "privileges": { + "items": { + "description": "The index level privileges that the role members have for the data streams and indices.", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "query": { + "description": "A search query that defines the documents the role members have read access to. A document within the specified data streams and indices must match this query in order for it to be accessible by the role members.", + "type": "string" + } + }, + "required": [ + "names", + "privileges" + ], + "type": "object" + }, + "type": "array" + }, + "remote_cluster": { + "items": { + "additionalProperties": false, + "properties": { + "clusters": { + "items": { + "description": "A list of remote cluster aliases. It supports literal strings as well as wildcards and regular expressions.", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "privileges": { + "items": { + "description": "The cluster level privileges for the remote cluster. The allowed values are a subset of the cluster privileges.", + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "privileges", + "clusters" + ], + "type": "object" + }, + "type": "array" + }, + "remote_indices": { + "items": { + "additionalProperties": false, + "properties": { + "allow_restricted_indices": { + "description": "Restricted indices are a special category of indices that are used internally to store configuration data and should not be directly accessed. Only internal system roles should normally grant privileges over the restricted indices. Toggling this flag is very strongly discouraged because it could effectively grant unrestricted operations on critical data, making the entire system unstable or leaking sensitive information. If for administrative purposes you need to create a role with privileges covering restricted indices, however, you can set this property to true. In that case, the names field will cover the restricted indices too.", + "type": "boolean" + }, + "clusters": { + "items": { + "description": "A list of remote cluster aliases. It supports literal strings as well as wildcards and regular expressions.", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "field_security": { + "additionalProperties": { + "items": { + "description": "The document fields that the role members have read access to.", + "type": "string" + }, + "type": "array" + }, + "type": "object" + }, + "names": { + "items": { + "description": "A list of remote aliases, data streams, or indices to which the permissions apply. It supports wildcards (*).", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "privileges": { + "items": { + "description": "The index level privileges that role members have for the specified indices.", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "query": { + "description": "A search query that defines the documents the role members have read access to. A document within the specified data streams and indices must match this query in order for it to be accessible by the role members. ", + "type": "string" + } + }, + "required": [ + "clusters", + "names", + "privileges" + ], + "type": "object" + }, + "type": "array" + }, + "run_as": { + "items": { + "description": "A user name that the role member can impersonate.", + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "kibana": { + "items": { + "additionalProperties": false, + "properties": { + "base": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "items": { + "description": "A base privilege that grants applies to all spaces.", + "type": "string" + }, + "type": "array" + }, + { + "items": { + "description": "A base privilege that applies to specific spaces.", + "type": "string" + }, + "type": "array" + } + ] + }, + "feature": { + "additionalProperties": { + "items": { + "description": "The privileges that the role member has for the feature.", + "type": "string" + }, + "type": "array" + }, + "type": "object" + }, + "spaces": { + "anyOf": [ + { + "items": { + "enum": [ + "*" + ], + "type": "string" + }, + "maxItems": 1, + "minItems": 1, + "type": "array" + }, + { + "items": { + "description": "A space that the privilege applies to.", + "type": "string" + }, + "type": "array" + } + ], + "default": [ + "*" + ] + } + }, + "required": [ + "base" + ], + "type": "object" + }, + "type": "array" + }, + "metadata": { + "additionalProperties": {}, + "type": "object" + } + }, + "required": [ + "elasticsearch" + ], + "type": "object" + }, + "type": "object" + } + }, + "required": [ + "roles" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Indicates a successful call." + } + }, + "summary": "Create or update roles", + "tags": [ + "roles" + ] + } + }, + "/api/spaces/_copy_saved_objects": { + "post": { + "description": "It also allows you to automatically copy related objects, so when you copy a dashboard, this can automatically copy over the associated visualizations, data views, and saved Discover sessions, as required. You can request to overwrite any objects that already exist in the target space if they share an identifier or you can use the resolve copy saved objects conflicts API to do this on a per-object basis.

[Required authorization] Route required privileges: copySavedObjectsToSpaces.", + "operationId": "post-spaces-copy-saved-objects", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "compatibilityMode": { + "default": false, + "description": "Apply various adjustments to the saved objects that are being copied to maintain compatibility between different Kibana versions. Use this option only if you encounter issues with copied saved objects. This option cannot be used with the `createNewCopies` option.", + "type": "boolean" + }, + "createNewCopies": { + "default": true, + "description": "Create new copies of saved objects, regenerate each object identifier, and reset the origin. When used, potential conflict errors are avoided. This option cannot be used with the `overwrite` and `compatibilityMode` options.", + "type": "boolean" + }, + "includeReferences": { + "default": false, + "description": "When set to true, all saved objects related to the specified saved objects will also be copied into the target spaces.", + "type": "boolean" + }, + "objects": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "description": "The identifier of the saved object to copy.", + "type": "string" + }, + "type": { + "description": "The type of the saved object to copy.", + "type": "string" + } + }, + "required": [ + "type", + "id" + ], + "type": "object" + }, + "type": "array" + }, + "overwrite": { + "default": false, + "description": "When set to true, all conflicts are automatically overridden. When a saved object with a matching type and identifier exists in the target space, that version is replaced with the version from the source space. This option cannot be used with the `createNewCopies` option.", + "type": "boolean" + }, + "spaces": { + "items": { + "description": "The identifiers of the spaces where you want to copy the specified objects.", + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "spaces", + "objects" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Copy saved objects between spaces", + "tags": [ + "spaces" + ] + } + }, + "/api/spaces/_disable_legacy_url_aliases": { + "post": { + "operationId": "post-spaces-disable-legacy-url-aliases", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "aliases": { + "items": { + "additionalProperties": false, + "properties": { + "sourceId": { + "description": "The alias source object identifier. This is the legacy object identifier.", + "type": "string" + }, + "targetSpace": { + "description": "The space where the alias target object exists.", + "type": "string" + }, + "targetType": { + "description": "The type of alias target object. ", + "type": "string" + } + }, + "required": [ + "targetSpace", + "targetType", + "sourceId" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "aliases" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Disable legacy URL aliases", + "tags": [ + "spaces" + ] + } + }, + "/api/spaces/_get_shareable_references": { + "post": { + "description": "Collect references and space contexts for saved objects.", + "operationId": "post-spaces-get-shareable-references", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "objects": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "objects" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Get shareable references", + "tags": [ + "spaces" + ] + } + }, + "/api/spaces/_resolve_copy_saved_objects_errors": { + "post": { + "description": "Overwrite saved objects that are returned as errors from the copy saved objects to space API.

[Required authorization] Route required privileges: copySavedObjectsToSpaces.", + "operationId": "post-spaces-resolve-copy-saved-objects-errors", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "compatibilityMode": { + "default": false, + "type": "boolean" + }, + "createNewCopies": { + "default": true, + "type": "boolean" + }, + "includeReferences": { + "default": false, + "type": "boolean" + }, + "objects": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "id" + ], + "type": "object" + }, + "type": "array" + }, + "retries": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "createNewCopy": { + "description": "Creates new copies of the saved objects, regenerates each object ID, and resets the origin.", + "type": "boolean" + }, + "destinationId": { + "description": "Specifies the destination identifier that the copied object should have, if different from the current identifier.", + "type": "string" + }, + "id": { + "description": "The saved object identifier.", + "type": "string" + }, + "ignoreMissingReferences": { + "description": "When set to true, any missing references errors are ignored.", + "type": "boolean" + }, + "overwrite": { + "default": false, + "description": "When set to true, the saved object from the source space overwrites the conflicting object in the destination space.", + "type": "boolean" + }, + "type": { + "description": "The saved object type.", + "type": "string" + } + }, + "required": [ + "type", + "id" + ], + "type": "object" + }, + "type": "array" + }, + "type": "object" + } + }, + "required": [ + "retries", + "objects" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Resolve conflicts copying saved objects", + "tags": [] + } + }, + "/api/spaces/_update_objects_spaces": { + "post": { + "description": "Update one or more saved objects to add or remove them from some spaces.", + "operationId": "post-spaces-update-objects-spaces", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "objects": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "description": "The identifier of the saved object to update.", + "type": "string" + }, + "type": { + "description": "The type of the saved object to update.", + "type": "string" + } + }, + "required": [ + "type", + "id" + ], + "type": "object" + }, + "type": "array" + }, + "spacesToAdd": { + "items": { + "description": "The identifiers of the spaces the saved objects should be added to or removed from.", + "type": "string" + }, + "type": "array" + }, + "spacesToRemove": { + "items": { + "description": "The identifiers of the spaces the saved objects should be added to or removed from.", + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "objects", + "spacesToAdd", + "spacesToRemove" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Update saved objects in spaces", + "tags": [ + "spaces" + ] + } + }, + "/api/spaces/space": { + "get": { + "operationId": "get-spaces-space", + "parameters": [ + { + "description": "Specifies which authorization checks are applied to the API call. The default value is `any`.", + "in": "query", + "name": "purpose", + "required": false, + "schema": { + "enum": [ + "any", + "copySavedObjectsIntoSpace", + "shareSavedObjectsIntoSpace" + ], + "type": "string" + } + }, + { + "description": "When enabled, the API returns any spaces that the user is authorized to access in any capacity and each space will contain the purposes for which the user is authorized. This can be useful to determine which spaces a user can read but not take a specific action in. If the security plugin is not enabled, this parameter has no effect, since no authorization checks take place. This parameter cannot be used in with the `purpose` parameter.", + "in": "query", + "name": "include_authorized_purposes", + "required": true, + "schema": { + "anyOf": [ + { + "items": {}, + "type": "array" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "object" + }, + { + "type": "string" + } + ], + "nullable": true, + "oneOf": [ + { + "enum": [ + false + ], + "type": "boolean", + "x-oas-optional": true + }, + { + "type": "boolean", + "x-oas-optional": true + } + ] + } + } + ], + "responses": { + "200": { + "description": "Indicates a successful call." + } + }, + "summary": "Get all spaces", + "tags": [ + "spaces" + ] + }, + "post": { + "operationId": "post-spaces-space", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "description": "The hexadecimal color code used in the space avatar. By default, the color is automatically generated from the space name.", + "type": "string" + }, + "description": { + "description": "A description for the space.", + "type": "string" + }, + "disabledFeatures": { + "default": [], + "items": { + "description": "The list of features that are turned off in the space.", + "type": "string" + }, + "type": "array" + }, + "id": { + "description": "The space ID that is part of the Kibana URL when inside the space. Space IDs are limited to lowercase alphanumeric, underscore, and hyphen characters (a-z, 0-9, _, and -). You are cannot change the ID with the update operation.", + "type": "string" + }, + "imageUrl": { + "description": "The data-URL encoded image to display in the space avatar. If specified, initials will not be displayed and the color will be visible as the background color for transparent images. For best results, your image should be 64x64. Images will not be optimized by this API call, so care should be taken when using custom images.", + "type": "string" + }, + "initials": { + "description": "One or two characters that are shown in the space avatar. By default, the initials are automatically generated from the space name.", + "maxLength": 2, + "type": "string" + }, + "name": { + "description": "The display name for the space. ", + "minLength": 1, + "type": "string" + }, + "solution": { + "enum": [ + "security", + "oblt", + "es", + "classic" + ], + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Indicates a successful call." + } + }, + "summary": "Create a space", + "tags": [ + "spaces" + ] + } + }, + "/api/spaces/space/{id}": { + "delete": { + "description": "When you delete a space, all saved objects that belong to the space are automatically deleted, which is permanent and cannot be undone.", + "operationId": "delete-spaces-space-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The space identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Indicates a successful call." + }, + "404": { + "description": "Indicates that the request failed." + } + }, + "summary": "Delete a space", + "tags": [ + "spaces" + ] + }, + "get": { + "operationId": "get-spaces-space-id", + "parameters": [ + { + "description": "The space identifier.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Indicates a successful call." + } + }, + "summary": "Get a space", + "tags": [ + "spaces" + ] + }, + "put": { + "operationId": "put-spaces-space-id", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The space identifier. You are unable to change the ID with the update operation.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "description": "The hexadecimal color code used in the space avatar. By default, the color is automatically generated from the space name.", + "type": "string" + }, + "description": { + "description": "A description for the space.", + "type": "string" + }, + "disabledFeatures": { + "default": [], + "items": { + "description": "The list of features that are turned off in the space.", + "type": "string" + }, + "type": "array" + }, + "id": { + "description": "The space ID that is part of the Kibana URL when inside the space. Space IDs are limited to lowercase alphanumeric, underscore, and hyphen characters (a-z, 0-9, _, and -). You are cannot change the ID with the update operation.", + "type": "string" + }, + "imageUrl": { + "description": "The data-URL encoded image to display in the space avatar. If specified, initials will not be displayed and the color will be visible as the background color for transparent images. For best results, your image should be 64x64. Images will not be optimized by this API call, so care should be taken when using custom images.", + "type": "string" + }, + "initials": { + "description": "One or two characters that are shown in the space avatar. By default, the initials are automatically generated from the space name.", + "maxLength": 2, + "type": "string" + }, + "name": { + "description": "The display name for the space. ", + "minLength": 1, + "type": "string" + }, + "solution": { + "enum": [ + "security", + "oblt", + "es", + "classic" + ], + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Indicates a successful call." + } + }, + "summary": "Update a space", + "tags": [ + "spaces" + ] + } + }, + "/api/status": { + "get": { + "operationId": "get-status", + "parameters": [ + { + "description": "Set to \"true\" to get the response in v7 format.", + "in": "query", + "name": "v7format", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Set to \"true\" to get the response in v8 format.", + "in": "query", + "name": "v8format", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/core_status_response" + }, + { + "$ref": "#/components/schemas/core_status_redactedResponse" + } + ], + "description": "Kibana's operational status. A minimal response is sent for unauthorized users." + } + } + }, + "description": "Overall status is OK and Kibana should be functioning normally." + }, + "503": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/core_status_response" + }, + { + "$ref": "#/components/schemas/core_status_redactedResponse" + } + ], + "description": "Kibana's operational status. A minimal response is sent for unauthorized users." + } + } + }, + "description": "Kibana or some of it's essential services are unavailable. Kibana may be degraded or unavailable." + } + }, + "summary": "Get Kibana's current status", + "tags": [ + "system" + ] + } + }, + "/api/streams": { + "get": { + "description": "Fetches list of all streams

[Required authorization] Route required privileges: read_stream.", + "operationId": "get-streams", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": {}, + "summary": "Get stream list", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/_disable": { + "post": { + "description": "Disables wired streams and deletes all existing stream definitions. The data of wired streams is deleted, but the data of classic streams is preserved.

[Required authorization] Route required privileges: manage_stream.", + "operationId": "post-streams-disable", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": {}, + "summary": "Disable streams", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/_enable": { + "post": { + "description": "Enables wired streams

[Required authorization] Route required privileges: manage_stream.", + "operationId": "post-streams-enable", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": {}, + "summary": "Enable streams", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/_resync": { + "post": { + "description": "Resyncs all streams, making sure that Elasticsearch assets are up to date

[Required authorization] Route required privileges: manage_stream.", + "operationId": "post-streams-resync", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": {}, + "summary": "Resync streams", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/{name}": { + "delete": { + "description": "Deletes a stream definition and the underlying data stream

[Required authorization] Route required privileges: manage_stream.", + "operationId": "delete-streams-name", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": {}, + "summary": "Delete a stream", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + }, + "get": { + "description": "Fetches a stream definition and associated dashboards

[Required authorization] Route required privileges: read_stream.", + "operationId": "get-streams-name", + "parameters": [ + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": {}, + "summary": "Get a stream", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + }, + "put": { + "description": "Creates or updates a stream definition. Classic streams can not be created through this API, only updated

[Required authorization] Route required privileges: manage_stream.", + "operationId": "put-streams-name", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "anyOf": [ + { + "allOf": [ + { + "properties": {}, + "type": "object" + }, + { + "properties": { + "stream": { + "allOf": [ + { + "additionalProperties": true, + "properties": { + "ingest": { + "additionalProperties": true, + "properties": { + "processing": { + "additionalProperties": true, + "properties": { + "updated_at": { + "not": {} + } + }, + "type": "object" + } + }, + "required": [ + "processing" + ], + "type": "object" + }, + "name": { + "not": {} + }, + "updated_at": { + "not": {} + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updated_at": { + "format": "date-time", + "type": "string" + } + }, + "required": [ + "name", + "description", + "updated_at" + ], + "type": "object" + } + ] + } + }, + "required": [ + "stream" + ], + "type": "object" + }, + { + "properties": { + "dashboards": { + "items": { + "type": "string" + }, + "type": "array" + }, + "queries": { + "items": { + "allOf": [ + { + "properties": { + "id": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "title": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "id", + "title" + ], + "type": "object" + }, + { + "properties": { + "evidence": { + "items": { + "type": "string" + }, + "type": "array" + }, + "feature": { + "additionalProperties": false, + "properties": { + "filter": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + "name": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "name", + "filter", + "type" + ], + "type": "object" + }, + "kql": { + "additionalProperties": false, + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "severity_score": { + "type": "number" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "rules": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "dashboards", + "rules", + "queries" + ], + "type": "object" + }, + { + "properties": { + "stream": { + "allOf": [ + { + "additionalProperties": true, + "properties": { + "ingest": { + "additionalProperties": true, + "properties": { + "processing": { + "additionalProperties": true, + "properties": { + "updated_at": { + "not": {} + } + }, + "type": "object" + } + }, + "required": [ + "processing" + ], + "type": "object" + }, + "name": { + "not": {} + }, + "updated_at": { + "not": {} + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "ingest": { + "allOf": [ + { + "properties": { + "failure_store": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + }, + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "enabled": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "enabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + } + ] + } + ] + }, + "lifecycle": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "dsl": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "dsl" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "ilm": { + "additionalProperties": false, + "properties": { + "policy": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "policy" + ], + "type": "object" + } + }, + "required": [ + "ilm" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + } + ] + }, + "processing": { + "additionalProperties": false, + "properties": { + "steps": { + "items": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "Grok processor - Extract fields from text using grok patterns", + "properties": { + "action": { + "enum": [ + "grok" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with grok patterns", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern_definitions": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "patterns": { + "description": "Grok patterns applied in order to extract fields", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "patterns" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Dissect processor - Extract fields from text using a lightweight, delimiter-based parser", + "properties": { + "action": { + "enum": [ + "dissect" + ], + "type": "string" + }, + "append_separator": { + "description": "Separator inserted when target fields are concatenated", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with dissect pattern", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern": { + "description": "Dissect pattern describing field boundaries", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Date processor - Parse dates from strings using one or more expected formats", + "properties": { + "action": { + "enum": [ + "date" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "formats": { + "description": "Accepted input date formats, tried in order", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "from": { + "description": "Source field containing the date/time text", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "locale": { + "description": "Optional locale for date parsing", + "minLength": 1, + "type": "string" + }, + "output_format": { + "description": "Optional output format for storing the parsed date as text", + "minLength": 1, + "type": "string" + }, + "timezone": { + "description": "Optional timezone for date parsing", + "minLength": 1, + "type": "string" + }, + "to": { + "description": "Target field for the parsed date (defaults to source)", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "formats" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "drop_document" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "math" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "expression": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "expression", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Rename processor - Change a field name and optionally its location", + "properties": { + "action": { + "enum": [ + "rename" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Existing source field to rename or move", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip when source field is missing", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting the target field if it already exists", + "type": "boolean" + }, + "to": { + "description": "New field name or destination path", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Set processor - Assign a literal or copied value to a field (mutually exclusive inputs)", + "properties": { + "action": { + "enum": [ + "set" + ], + "type": "string" + }, + "copy_from": { + "description": "Copy value from another field instead of providing a literal", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting an existing target field", + "type": "boolean" + }, + "to": { + "description": "Target field to set or create", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Literal value to assign to the target field" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Append processor - Append one or more values to an existing or new array field", + "properties": { + "action": { + "enum": [ + "append" + ], + "type": "string" + }, + "allow_duplicates": { + "description": "If true, do not deduplicate appended values", + "type": "boolean" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "to": { + "description": "Array field to append values to", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Values to append (must be literal, no templates)", + "items": {}, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove by prefix processor - Remove a field and all nested fields matching the prefix", + "properties": { + "action": { + "enum": [ + "remove_by_prefix" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove along with all its nested fields", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove processor - Delete one or more fields from the document", + "properties": { + "action": { + "enum": [ + "remove" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove from the document", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "replace" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "pattern": { + "description": "A non-empty string or string with whitespace.", + "minLength": 1, + "type": "string" + }, + "replacement": { + "type": "string" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern", + "replacement" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "uppercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "lowercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "trim" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "join" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "delimiter": { + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "delimiter", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Convert processor - Change the data type of a field value (integer, long, double, boolean, or string)", + "properties": { + "action": { + "enum": [ + "convert" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to convert to a different data type", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "to": { + "description": "Target field for the converted value (defaults to source)", + "minLength": 1, + "type": "string" + }, + "type": { + "description": "Target data type: integer, long, double, boolean, or string", + "enum": [ + "integer", + "long", + "double", + "boolean", + "string" + ], + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "concat" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "field" + ], + "type": "string" + }, + "value": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "literal" + ], + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + } + ] + }, + "minItems": 1, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Manual ingest pipeline wrapper around native Elasticsearch processors", + "properties": { + "action": { + "description": "Manual ingest pipeline - executes raw Elasticsearch ingest processors", + "enum": [ + "manual_ingest_pipeline" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "on_failure": { + "description": "Fallback processors to run when a processor fails", + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "processors": { + "description": "List of raw Elasticsearch ingest processors to run", + "items": { + "additionalProperties": false, + "properties": { + "append": {}, + "attachment": {}, + "bytes": {}, + "circle": {}, + "community_id": {}, + "convert": {}, + "csv": {}, + "date": {}, + "date_index_name": {}, + "dissect": {}, + "dot_expander": {}, + "drop": {}, + "enrich": {}, + "fail": {}, + "fingerprint": {}, + "foreach": {}, + "geo_grid": {}, + "geoip": {}, + "grok": {}, + "gsub": {}, + "html_strip": {}, + "inference": {}, + "ip_location": {}, + "join": {}, + "json": {}, + "kv": {}, + "lowercase": {}, + "network_direction": {}, + "pipeline": {}, + "redact": {}, + "registered_domain": {}, + "remove": {}, + "rename": {}, + "reroute": {}, + "script": {}, + "set": {}, + "set_security_user": {}, + "sort": {}, + "split": {}, + "terminate": {}, + "trim": {}, + "uppercase": {}, + "uri_parts": {}, + "urldecode": {}, + "user_agent": {} + }, + "required": [ + "append", + "attachment", + "bytes", + "circle", + "community_id", + "convert", + "csv", + "date", + "date_index_name", + "dissect", + "dot_expander", + "drop", + "enrich", + "fail", + "fingerprint", + "foreach", + "ip_location", + "geo_grid", + "geoip", + "grok", + "gsub", + "html_strip", + "inference", + "join", + "json", + "kv", + "lowercase", + "network_direction", + "pipeline", + "redact", + "registered_domain", + "remove", + "rename", + "reroute", + "script", + "set", + "set_security_user", + "sort", + "split", + "terminate", + "trim", + "uppercase", + "urldecode", + "uri_parts", + "user_agent" + ], + "type": "object" + }, + "type": "array" + }, + "tag": { + "description": "Optional ingest processor tag for Elasticsearch", + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "processors" + ], + "type": "object" + } + ] + }, + { + "additionalProperties": false, + "properties": { + "condition": { + "allOf": [ + { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + { + "properties": { + "steps": { + "items": {}, + "type": "array" + } + }, + "required": [ + "steps" + ], + "type": "object" + } + ] + }, + "customIdentifier": { + "type": "string" + } + }, + "required": [ + "condition" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "updated_at": { + "format": "date-time", + "type": "string" + } + }, + "required": [ + "steps", + "updated_at" + ], + "type": "object" + }, + "settings": { + "additionalProperties": false, + "properties": { + "index.number_of_replicas": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.number_of_shards": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.refresh_interval": { + "additionalProperties": false, + "properties": { + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + -1 + ], + "type": "number" + } + ] + } + }, + "required": [ + "value" + ], + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "lifecycle", + "processing", + "settings", + "failure_store" + ], + "type": "object" + }, + { + "properties": { + "wired": { + "additionalProperties": false, + "properties": { + "fields": { + "additionalProperties": { + "allOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + }, + "type": "array" + }, + { + "items": {}, + "type": "array" + }, + {} + ] + }, + "type": "object" + }, + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "format": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": { + "enum": [ + "keyword", + "match_only_text", + "long", + "double", + "date", + "boolean", + "ip", + "geo_point" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ] + } + ] + }, + "type": "object" + }, + "routing": { + "items": { + "additionalProperties": false, + "properties": { + "destination": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "status": { + "enum": [ + "enabled", + "disabled" + ], + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + } + }, + "required": [ + "destination", + "where" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "fields", + "routing" + ], + "type": "object" + } + }, + "required": [ + "wired" + ], + "type": "object" + } + ] + } + }, + "required": [ + "ingest" + ], + "type": "object" + } + ] + } + }, + "required": [ + "stream" + ], + "type": "object" + }, + { + "properties": {}, + "type": "object" + }, + { + "properties": { + "stream": { + "allOf": [ + { + "additionalProperties": true, + "properties": { + "ingest": { + "additionalProperties": true, + "properties": { + "processing": { + "additionalProperties": true, + "properties": { + "updated_at": { + "not": {} + } + }, + "type": "object" + } + }, + "required": [ + "processing" + ], + "type": "object" + }, + "name": { + "not": {} + }, + "updated_at": { + "not": {} + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updated_at": { + "format": "date-time", + "type": "string" + } + }, + "required": [ + "name", + "description", + "updated_at" + ], + "type": "object" + } + ] + } + }, + "required": [ + "stream" + ], + "type": "object" + }, + { + "properties": { + "dashboards": { + "items": { + "type": "string" + }, + "type": "array" + }, + "queries": { + "items": { + "allOf": [ + { + "properties": { + "id": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "title": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "id", + "title" + ], + "type": "object" + }, + { + "properties": { + "evidence": { + "items": { + "type": "string" + }, + "type": "array" + }, + "feature": { + "additionalProperties": false, + "properties": { + "filter": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + "name": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "name", + "filter", + "type" + ], + "type": "object" + }, + "kql": { + "additionalProperties": false, + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "severity_score": { + "type": "number" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "rules": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "dashboards", + "rules", + "queries" + ], + "type": "object" + }, + { + "properties": { + "stream": { + "allOf": [ + { + "additionalProperties": true, + "properties": { + "ingest": { + "additionalProperties": true, + "properties": { + "processing": { + "additionalProperties": true, + "properties": { + "updated_at": { + "not": {} + } + }, + "type": "object" + } + }, + "required": [ + "processing" + ], + "type": "object" + }, + "name": { + "not": {} + }, + "updated_at": { + "not": {} + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "ingest": { + "additionalProperties": false, + "properties": { + "failure_store": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + }, + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "enabled": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "enabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + } + ] + } + ] + }, + "lifecycle": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "dsl": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "dsl" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "ilm": { + "additionalProperties": false, + "properties": { + "policy": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "policy" + ], + "type": "object" + } + }, + "required": [ + "ilm" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + } + ] + }, + "processing": { + "additionalProperties": false, + "properties": { + "steps": { + "items": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "Grok processor - Extract fields from text using grok patterns", + "properties": { + "action": { + "enum": [ + "grok" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with grok patterns", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern_definitions": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "patterns": { + "description": "Grok patterns applied in order to extract fields", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "patterns" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Dissect processor - Extract fields from text using a lightweight, delimiter-based parser", + "properties": { + "action": { + "enum": [ + "dissect" + ], + "type": "string" + }, + "append_separator": { + "description": "Separator inserted when target fields are concatenated", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with dissect pattern", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern": { + "description": "Dissect pattern describing field boundaries", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Date processor - Parse dates from strings using one or more expected formats", + "properties": { + "action": { + "enum": [ + "date" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "formats": { + "description": "Accepted input date formats, tried in order", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "from": { + "description": "Source field containing the date/time text", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "locale": { + "description": "Optional locale for date parsing", + "minLength": 1, + "type": "string" + }, + "output_format": { + "description": "Optional output format for storing the parsed date as text", + "minLength": 1, + "type": "string" + }, + "timezone": { + "description": "Optional timezone for date parsing", + "minLength": 1, + "type": "string" + }, + "to": { + "description": "Target field for the parsed date (defaults to source)", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "formats" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "drop_document" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "math" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "expression": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "expression", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Rename processor - Change a field name and optionally its location", + "properties": { + "action": { + "enum": [ + "rename" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Existing source field to rename or move", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip when source field is missing", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting the target field if it already exists", + "type": "boolean" + }, + "to": { + "description": "New field name or destination path", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Set processor - Assign a literal or copied value to a field (mutually exclusive inputs)", + "properties": { + "action": { + "enum": [ + "set" + ], + "type": "string" + }, + "copy_from": { + "description": "Copy value from another field instead of providing a literal", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting an existing target field", + "type": "boolean" + }, + "to": { + "description": "Target field to set or create", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Literal value to assign to the target field" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Append processor - Append one or more values to an existing or new array field", + "properties": { + "action": { + "enum": [ + "append" + ], + "type": "string" + }, + "allow_duplicates": { + "description": "If true, do not deduplicate appended values", + "type": "boolean" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "to": { + "description": "Array field to append values to", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Values to append (must be literal, no templates)", + "items": {}, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove by prefix processor - Remove a field and all nested fields matching the prefix", + "properties": { + "action": { + "enum": [ + "remove_by_prefix" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove along with all its nested fields", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove processor - Delete one or more fields from the document", + "properties": { + "action": { + "enum": [ + "remove" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove from the document", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "replace" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "pattern": { + "description": "A non-empty string or string with whitespace.", + "minLength": 1, + "type": "string" + }, + "replacement": { + "type": "string" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern", + "replacement" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "uppercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "lowercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "trim" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "join" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "delimiter": { + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "delimiter", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Convert processor - Change the data type of a field value (integer, long, double, boolean, or string)", + "properties": { + "action": { + "enum": [ + "convert" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to convert to a different data type", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "to": { + "description": "Target field for the converted value (defaults to source)", + "minLength": 1, + "type": "string" + }, + "type": { + "description": "Target data type: integer, long, double, boolean, or string", + "enum": [ + "integer", + "long", + "double", + "boolean", + "string" + ], + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "concat" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "field" + ], + "type": "string" + }, + "value": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "literal" + ], + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + } + ] + }, + "minItems": 1, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Manual ingest pipeline wrapper around native Elasticsearch processors", + "properties": { + "action": { + "description": "Manual ingest pipeline - executes raw Elasticsearch ingest processors", + "enum": [ + "manual_ingest_pipeline" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "on_failure": { + "description": "Fallback processors to run when a processor fails", + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "processors": { + "description": "List of raw Elasticsearch ingest processors to run", + "items": { + "additionalProperties": false, + "properties": { + "append": {}, + "attachment": {}, + "bytes": {}, + "circle": {}, + "community_id": {}, + "convert": {}, + "csv": {}, + "date": {}, + "date_index_name": {}, + "dissect": {}, + "dot_expander": {}, + "drop": {}, + "enrich": {}, + "fail": {}, + "fingerprint": {}, + "foreach": {}, + "geo_grid": {}, + "geoip": {}, + "grok": {}, + "gsub": {}, + "html_strip": {}, + "inference": {}, + "ip_location": {}, + "join": {}, + "json": {}, + "kv": {}, + "lowercase": {}, + "network_direction": {}, + "pipeline": {}, + "redact": {}, + "registered_domain": {}, + "remove": {}, + "rename": {}, + "reroute": {}, + "script": {}, + "set": {}, + "set_security_user": {}, + "sort": {}, + "split": {}, + "terminate": {}, + "trim": {}, + "uppercase": {}, + "uri_parts": {}, + "urldecode": {}, + "user_agent": {} + }, + "required": [ + "append", + "attachment", + "bytes", + "circle", + "community_id", + "convert", + "csv", + "date", + "date_index_name", + "dissect", + "dot_expander", + "drop", + "enrich", + "fail", + "fingerprint", + "foreach", + "ip_location", + "geo_grid", + "geoip", + "grok", + "gsub", + "html_strip", + "inference", + "join", + "json", + "kv", + "lowercase", + "network_direction", + "pipeline", + "redact", + "registered_domain", + "remove", + "rename", + "reroute", + "script", + "set", + "set_security_user", + "sort", + "split", + "terminate", + "trim", + "uppercase", + "urldecode", + "uri_parts", + "user_agent" + ], + "type": "object" + }, + "type": "array" + }, + "tag": { + "description": "Optional ingest processor tag for Elasticsearch", + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "processors" + ], + "type": "object" + } + ] + }, + { + "additionalProperties": false, + "properties": { + "condition": { + "allOf": [ + { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + { + "properties": { + "steps": { + "items": {}, + "type": "array" + } + }, + "required": [ + "steps" + ], + "type": "object" + } + ] + }, + "customIdentifier": { + "type": "string" + } + }, + "required": [ + "condition" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "updated_at": { + "format": "date-time", + "type": "string" + } + }, + "required": [ + "steps", + "updated_at" + ], + "type": "object" + }, + "settings": { + "additionalProperties": false, + "properties": { + "index.number_of_replicas": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.number_of_shards": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.refresh_interval": { + "additionalProperties": false, + "properties": { + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + -1 + ], + "type": "number" + } + ] + } + }, + "required": [ + "value" + ], + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "lifecycle", + "processing", + "settings", + "failure_store" + ], + "type": "object" + } + }, + "required": [ + "ingest" + ], + "type": "object" + } + ] + } + }, + "required": [ + "stream" + ], + "type": "object" + }, + { + "properties": {}, + "type": "object" + }, + { + "properties": {}, + "type": "object" + } + ] + }, + { + "allOf": [ + { + "properties": {}, + "type": "object" + }, + { + "properties": { + "stream": { + "allOf": [ + { + "additionalProperties": true, + "properties": { + "ingest": { + "additionalProperties": true, + "properties": { + "processing": { + "additionalProperties": true, + "properties": { + "updated_at": { + "not": {} + } + }, + "type": "object" + } + }, + "required": [ + "processing" + ], + "type": "object" + }, + "name": { + "not": {} + }, + "updated_at": { + "not": {} + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updated_at": { + "format": "date-time", + "type": "string" + } + }, + "required": [ + "name", + "description", + "updated_at" + ], + "type": "object" + } + ] + } + }, + "required": [ + "stream" + ], + "type": "object" + }, + { + "properties": { + "dashboards": { + "items": { + "type": "string" + }, + "type": "array" + }, + "queries": { + "items": { + "allOf": [ + { + "properties": { + "id": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "title": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "id", + "title" + ], + "type": "object" + }, + { + "properties": { + "evidence": { + "items": { + "type": "string" + }, + "type": "array" + }, + "feature": { + "additionalProperties": false, + "properties": { + "filter": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + "name": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "name", + "filter", + "type" + ], + "type": "object" + }, + "kql": { + "additionalProperties": false, + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "severity_score": { + "type": "number" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "rules": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "dashboards", + "rules", + "queries" + ], + "type": "object" + }, + { + "properties": { + "stream": { + "allOf": [ + { + "additionalProperties": true, + "properties": { + "ingest": { + "additionalProperties": true, + "properties": { + "processing": { + "additionalProperties": true, + "properties": { + "updated_at": { + "not": {} + } + }, + "type": "object" + } + }, + "required": [ + "processing" + ], + "type": "object" + }, + "name": { + "not": {} + }, + "updated_at": { + "not": {} + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "ingest": { + "allOf": [ + { + "properties": { + "failure_store": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + }, + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "enabled": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "enabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + } + ] + } + ] + }, + "lifecycle": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "dsl": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "dsl" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "ilm": { + "additionalProperties": false, + "properties": { + "policy": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "policy" + ], + "type": "object" + } + }, + "required": [ + "ilm" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + } + ] + }, + "processing": { + "additionalProperties": false, + "properties": { + "steps": { + "items": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "Grok processor - Extract fields from text using grok patterns", + "properties": { + "action": { + "enum": [ + "grok" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with grok patterns", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern_definitions": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "patterns": { + "description": "Grok patterns applied in order to extract fields", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "patterns" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Dissect processor - Extract fields from text using a lightweight, delimiter-based parser", + "properties": { + "action": { + "enum": [ + "dissect" + ], + "type": "string" + }, + "append_separator": { + "description": "Separator inserted when target fields are concatenated", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with dissect pattern", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern": { + "description": "Dissect pattern describing field boundaries", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Date processor - Parse dates from strings using one or more expected formats", + "properties": { + "action": { + "enum": [ + "date" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "formats": { + "description": "Accepted input date formats, tried in order", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "from": { + "description": "Source field containing the date/time text", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "locale": { + "description": "Optional locale for date parsing", + "minLength": 1, + "type": "string" + }, + "output_format": { + "description": "Optional output format for storing the parsed date as text", + "minLength": 1, + "type": "string" + }, + "timezone": { + "description": "Optional timezone for date parsing", + "minLength": 1, + "type": "string" + }, + "to": { + "description": "Target field for the parsed date (defaults to source)", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "formats" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "drop_document" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "math" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "expression": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "expression", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Rename processor - Change a field name and optionally its location", + "properties": { + "action": { + "enum": [ + "rename" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Existing source field to rename or move", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip when source field is missing", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting the target field if it already exists", + "type": "boolean" + }, + "to": { + "description": "New field name or destination path", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Set processor - Assign a literal or copied value to a field (mutually exclusive inputs)", + "properties": { + "action": { + "enum": [ + "set" + ], + "type": "string" + }, + "copy_from": { + "description": "Copy value from another field instead of providing a literal", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting an existing target field", + "type": "boolean" + }, + "to": { + "description": "Target field to set or create", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Literal value to assign to the target field" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Append processor - Append one or more values to an existing or new array field", + "properties": { + "action": { + "enum": [ + "append" + ], + "type": "string" + }, + "allow_duplicates": { + "description": "If true, do not deduplicate appended values", + "type": "boolean" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "to": { + "description": "Array field to append values to", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Values to append (must be literal, no templates)", + "items": {}, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove by prefix processor - Remove a field and all nested fields matching the prefix", + "properties": { + "action": { + "enum": [ + "remove_by_prefix" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove along with all its nested fields", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove processor - Delete one or more fields from the document", + "properties": { + "action": { + "enum": [ + "remove" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove from the document", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "replace" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "pattern": { + "description": "A non-empty string or string with whitespace.", + "minLength": 1, + "type": "string" + }, + "replacement": { + "type": "string" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern", + "replacement" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "uppercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "lowercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "trim" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "join" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "delimiter": { + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "delimiter", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Convert processor - Change the data type of a field value (integer, long, double, boolean, or string)", + "properties": { + "action": { + "enum": [ + "convert" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to convert to a different data type", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "to": { + "description": "Target field for the converted value (defaults to source)", + "minLength": 1, + "type": "string" + }, + "type": { + "description": "Target data type: integer, long, double, boolean, or string", + "enum": [ + "integer", + "long", + "double", + "boolean", + "string" + ], + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "concat" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "field" + ], + "type": "string" + }, + "value": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "literal" + ], + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + } + ] + }, + "minItems": 1, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Manual ingest pipeline wrapper around native Elasticsearch processors", + "properties": { + "action": { + "description": "Manual ingest pipeline - executes raw Elasticsearch ingest processors", + "enum": [ + "manual_ingest_pipeline" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "on_failure": { + "description": "Fallback processors to run when a processor fails", + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "processors": { + "description": "List of raw Elasticsearch ingest processors to run", + "items": { + "additionalProperties": false, + "properties": { + "append": {}, + "attachment": {}, + "bytes": {}, + "circle": {}, + "community_id": {}, + "convert": {}, + "csv": {}, + "date": {}, + "date_index_name": {}, + "dissect": {}, + "dot_expander": {}, + "drop": {}, + "enrich": {}, + "fail": {}, + "fingerprint": {}, + "foreach": {}, + "geo_grid": {}, + "geoip": {}, + "grok": {}, + "gsub": {}, + "html_strip": {}, + "inference": {}, + "ip_location": {}, + "join": {}, + "json": {}, + "kv": {}, + "lowercase": {}, + "network_direction": {}, + "pipeline": {}, + "redact": {}, + "registered_domain": {}, + "remove": {}, + "rename": {}, + "reroute": {}, + "script": {}, + "set": {}, + "set_security_user": {}, + "sort": {}, + "split": {}, + "terminate": {}, + "trim": {}, + "uppercase": {}, + "uri_parts": {}, + "urldecode": {}, + "user_agent": {} + }, + "required": [ + "append", + "attachment", + "bytes", + "circle", + "community_id", + "convert", + "csv", + "date", + "date_index_name", + "dissect", + "dot_expander", + "drop", + "enrich", + "fail", + "fingerprint", + "foreach", + "ip_location", + "geo_grid", + "geoip", + "grok", + "gsub", + "html_strip", + "inference", + "join", + "json", + "kv", + "lowercase", + "network_direction", + "pipeline", + "redact", + "registered_domain", + "remove", + "rename", + "reroute", + "script", + "set", + "set_security_user", + "sort", + "split", + "terminate", + "trim", + "uppercase", + "urldecode", + "uri_parts", + "user_agent" + ], + "type": "object" + }, + "type": "array" + }, + "tag": { + "description": "Optional ingest processor tag for Elasticsearch", + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "processors" + ], + "type": "object" + } + ] + }, + { + "additionalProperties": false, + "properties": { + "condition": { + "allOf": [ + { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + { + "properties": { + "steps": { + "items": {}, + "type": "array" + } + }, + "required": [ + "steps" + ], + "type": "object" + } + ] + }, + "customIdentifier": { + "type": "string" + } + }, + "required": [ + "condition" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "updated_at": { + "format": "date-time", + "type": "string" + } + }, + "required": [ + "steps", + "updated_at" + ], + "type": "object" + }, + "settings": { + "additionalProperties": false, + "properties": { + "index.number_of_replicas": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.number_of_shards": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.refresh_interval": { + "additionalProperties": false, + "properties": { + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + -1 + ], + "type": "number" + } + ] + } + }, + "required": [ + "value" + ], + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "lifecycle", + "processing", + "settings", + "failure_store" + ], + "type": "object" + }, + { + "properties": { + "classic": { + "additionalProperties": false, + "properties": { + "field_overrides": { + "additionalProperties": { + "allOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + }, + "type": "array" + }, + { + "items": {}, + "type": "array" + }, + {} + ] + }, + "type": "object" + }, + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "format": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": { + "enum": [ + "keyword", + "match_only_text", + "long", + "double", + "date", + "boolean", + "ip", + "geo_point" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ] + } + ] + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "classic" + ], + "type": "object" + } + ] + } + }, + "required": [ + "ingest" + ], + "type": "object" + } + ] + } + }, + "required": [ + "stream" + ], + "type": "object" + }, + { + "properties": {}, + "type": "object" + }, + { + "properties": { + "stream": { + "allOf": [ + { + "additionalProperties": true, + "properties": { + "ingest": { + "additionalProperties": true, + "properties": { + "processing": { + "additionalProperties": true, + "properties": { + "updated_at": { + "not": {} + } + }, + "type": "object" + } + }, + "required": [ + "processing" + ], + "type": "object" + }, + "name": { + "not": {} + }, + "updated_at": { + "not": {} + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updated_at": { + "format": "date-time", + "type": "string" + } + }, + "required": [ + "name", + "description", + "updated_at" + ], + "type": "object" + } + ] + } + }, + "required": [ + "stream" + ], + "type": "object" + }, + { + "properties": { + "dashboards": { + "items": { + "type": "string" + }, + "type": "array" + }, + "queries": { + "items": { + "allOf": [ + { + "properties": { + "id": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "title": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "id", + "title" + ], + "type": "object" + }, + { + "properties": { + "evidence": { + "items": { + "type": "string" + }, + "type": "array" + }, + "feature": { + "additionalProperties": false, + "properties": { + "filter": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + "name": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "name", + "filter", + "type" + ], + "type": "object" + }, + "kql": { + "additionalProperties": false, + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "severity_score": { + "type": "number" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "rules": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "dashboards", + "rules", + "queries" + ], + "type": "object" + }, + { + "properties": { + "stream": { + "allOf": [ + { + "additionalProperties": true, + "properties": { + "ingest": { + "additionalProperties": true, + "properties": { + "processing": { + "additionalProperties": true, + "properties": { + "updated_at": { + "not": {} + } + }, + "type": "object" + } + }, + "required": [ + "processing" + ], + "type": "object" + }, + "name": { + "not": {} + }, + "updated_at": { + "not": {} + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "ingest": { + "additionalProperties": false, + "properties": { + "failure_store": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + }, + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "enabled": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "enabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + } + ] + } + ] + }, + "lifecycle": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "dsl": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "dsl" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "ilm": { + "additionalProperties": false, + "properties": { + "policy": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "policy" + ], + "type": "object" + } + }, + "required": [ + "ilm" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + } + ] + }, + "processing": { + "additionalProperties": false, + "properties": { + "steps": { + "items": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "Grok processor - Extract fields from text using grok patterns", + "properties": { + "action": { + "enum": [ + "grok" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with grok patterns", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern_definitions": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "patterns": { + "description": "Grok patterns applied in order to extract fields", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "patterns" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Dissect processor - Extract fields from text using a lightweight, delimiter-based parser", + "properties": { + "action": { + "enum": [ + "dissect" + ], + "type": "string" + }, + "append_separator": { + "description": "Separator inserted when target fields are concatenated", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with dissect pattern", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern": { + "description": "Dissect pattern describing field boundaries", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Date processor - Parse dates from strings using one or more expected formats", + "properties": { + "action": { + "enum": [ + "date" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "formats": { + "description": "Accepted input date formats, tried in order", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "from": { + "description": "Source field containing the date/time text", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "locale": { + "description": "Optional locale for date parsing", + "minLength": 1, + "type": "string" + }, + "output_format": { + "description": "Optional output format for storing the parsed date as text", + "minLength": 1, + "type": "string" + }, + "timezone": { + "description": "Optional timezone for date parsing", + "minLength": 1, + "type": "string" + }, + "to": { + "description": "Target field for the parsed date (defaults to source)", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "formats" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "drop_document" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "math" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "expression": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "expression", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Rename processor - Change a field name and optionally its location", + "properties": { + "action": { + "enum": [ + "rename" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Existing source field to rename or move", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip when source field is missing", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting the target field if it already exists", + "type": "boolean" + }, + "to": { + "description": "New field name or destination path", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Set processor - Assign a literal or copied value to a field (mutually exclusive inputs)", + "properties": { + "action": { + "enum": [ + "set" + ], + "type": "string" + }, + "copy_from": { + "description": "Copy value from another field instead of providing a literal", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting an existing target field", + "type": "boolean" + }, + "to": { + "description": "Target field to set or create", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Literal value to assign to the target field" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Append processor - Append one or more values to an existing or new array field", + "properties": { + "action": { + "enum": [ + "append" + ], + "type": "string" + }, + "allow_duplicates": { + "description": "If true, do not deduplicate appended values", + "type": "boolean" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "to": { + "description": "Array field to append values to", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Values to append (must be literal, no templates)", + "items": {}, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove by prefix processor - Remove a field and all nested fields matching the prefix", + "properties": { + "action": { + "enum": [ + "remove_by_prefix" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove along with all its nested fields", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove processor - Delete one or more fields from the document", + "properties": { + "action": { + "enum": [ + "remove" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove from the document", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "replace" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "pattern": { + "description": "A non-empty string or string with whitespace.", + "minLength": 1, + "type": "string" + }, + "replacement": { + "type": "string" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern", + "replacement" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "uppercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "lowercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "trim" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "join" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "delimiter": { + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "delimiter", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Convert processor - Change the data type of a field value (integer, long, double, boolean, or string)", + "properties": { + "action": { + "enum": [ + "convert" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to convert to a different data type", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "to": { + "description": "Target field for the converted value (defaults to source)", + "minLength": 1, + "type": "string" + }, + "type": { + "description": "Target data type: integer, long, double, boolean, or string", + "enum": [ + "integer", + "long", + "double", + "boolean", + "string" + ], + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "concat" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "field" + ], + "type": "string" + }, + "value": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "literal" + ], + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + } + ] + }, + "minItems": 1, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Manual ingest pipeline wrapper around native Elasticsearch processors", + "properties": { + "action": { + "description": "Manual ingest pipeline - executes raw Elasticsearch ingest processors", + "enum": [ + "manual_ingest_pipeline" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "on_failure": { + "description": "Fallback processors to run when a processor fails", + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "processors": { + "description": "List of raw Elasticsearch ingest processors to run", + "items": { + "additionalProperties": false, + "properties": { + "append": {}, + "attachment": {}, + "bytes": {}, + "circle": {}, + "community_id": {}, + "convert": {}, + "csv": {}, + "date": {}, + "date_index_name": {}, + "dissect": {}, + "dot_expander": {}, + "drop": {}, + "enrich": {}, + "fail": {}, + "fingerprint": {}, + "foreach": {}, + "geo_grid": {}, + "geoip": {}, + "grok": {}, + "gsub": {}, + "html_strip": {}, + "inference": {}, + "ip_location": {}, + "join": {}, + "json": {}, + "kv": {}, + "lowercase": {}, + "network_direction": {}, + "pipeline": {}, + "redact": {}, + "registered_domain": {}, + "remove": {}, + "rename": {}, + "reroute": {}, + "script": {}, + "set": {}, + "set_security_user": {}, + "sort": {}, + "split": {}, + "terminate": {}, + "trim": {}, + "uppercase": {}, + "uri_parts": {}, + "urldecode": {}, + "user_agent": {} + }, + "required": [ + "append", + "attachment", + "bytes", + "circle", + "community_id", + "convert", + "csv", + "date", + "date_index_name", + "dissect", + "dot_expander", + "drop", + "enrich", + "fail", + "fingerprint", + "foreach", + "ip_location", + "geo_grid", + "geoip", + "grok", + "gsub", + "html_strip", + "inference", + "join", + "json", + "kv", + "lowercase", + "network_direction", + "pipeline", + "redact", + "registered_domain", + "remove", + "rename", + "reroute", + "script", + "set", + "set_security_user", + "sort", + "split", + "terminate", + "trim", + "uppercase", + "urldecode", + "uri_parts", + "user_agent" + ], + "type": "object" + }, + "type": "array" + }, + "tag": { + "description": "Optional ingest processor tag for Elasticsearch", + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "processors" + ], + "type": "object" + } + ] + }, + { + "additionalProperties": false, + "properties": { + "condition": { + "allOf": [ + { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + { + "properties": { + "steps": { + "items": {}, + "type": "array" + } + }, + "required": [ + "steps" + ], + "type": "object" + } + ] + }, + "customIdentifier": { + "type": "string" + } + }, + "required": [ + "condition" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "updated_at": { + "format": "date-time", + "type": "string" + } + }, + "required": [ + "steps", + "updated_at" + ], + "type": "object" + }, + "settings": { + "additionalProperties": false, + "properties": { + "index.number_of_replicas": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.number_of_shards": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.refresh_interval": { + "additionalProperties": false, + "properties": { + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + -1 + ], + "type": "number" + } + ] + } + }, + "required": [ + "value" + ], + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "lifecycle", + "processing", + "settings", + "failure_store" + ], + "type": "object" + } + }, + "required": [ + "ingest" + ], + "type": "object" + } + ] + } + }, + "required": [ + "stream" + ], + "type": "object" + }, + { + "properties": {}, + "type": "object" + }, + { + "properties": {}, + "type": "object" + } + ] + } + ] + } + ] + } + } + } + }, + "responses": {}, + "summary": "Create or update a stream", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/{name}/_fork": { + "post": { + "description": "Forks a wired stream and creates a child stream

[Required authorization] Route required privileges: manage_stream.", + "operationId": "post-streams-name-fork", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "status": { + "enum": [ + "enabled", + "disabled" + ], + "type": "string" + }, + "stream": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + } + }, + "required": [ + "stream", + "where" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Fork a stream", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/{name}/_ingest": { + "get": { + "description": "Fetches the ingest settings of an ingest stream definition

[Required authorization] Route required privileges: read_stream.", + "operationId": "get-streams-name-ingest", + "parameters": [ + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": {}, + "summary": "Get ingest stream settings", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + }, + "put": { + "description": "Upserts the ingest settings of an ingest stream definition

[Required authorization] Route required privileges: manage_stream.", + "operationId": "put-streams-name-ingest", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "ingest": { + "anyOf": [ + { + "allOf": [ + { + "properties": { + "failure_store": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + }, + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "enabled": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "enabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + } + ] + } + ] + }, + "lifecycle": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "dsl": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "dsl" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "ilm": { + "additionalProperties": false, + "properties": { + "policy": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "policy" + ], + "type": "object" + } + }, + "required": [ + "ilm" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + } + ] + }, + "processing": { + "additionalProperties": false, + "properties": { + "steps": { + "items": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "Grok processor - Extract fields from text using grok patterns", + "properties": { + "action": { + "enum": [ + "grok" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with grok patterns", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern_definitions": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "patterns": { + "description": "Grok patterns applied in order to extract fields", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "patterns" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Dissect processor - Extract fields from text using a lightweight, delimiter-based parser", + "properties": { + "action": { + "enum": [ + "dissect" + ], + "type": "string" + }, + "append_separator": { + "description": "Separator inserted when target fields are concatenated", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with dissect pattern", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern": { + "description": "Dissect pattern describing field boundaries", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Date processor - Parse dates from strings using one or more expected formats", + "properties": { + "action": { + "enum": [ + "date" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "formats": { + "description": "Accepted input date formats, tried in order", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "from": { + "description": "Source field containing the date/time text", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "locale": { + "description": "Optional locale for date parsing", + "minLength": 1, + "type": "string" + }, + "output_format": { + "description": "Optional output format for storing the parsed date as text", + "minLength": 1, + "type": "string" + }, + "timezone": { + "description": "Optional timezone for date parsing", + "minLength": 1, + "type": "string" + }, + "to": { + "description": "Target field for the parsed date (defaults to source)", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "formats" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "drop_document" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "math" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "expression": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "expression", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Rename processor - Change a field name and optionally its location", + "properties": { + "action": { + "enum": [ + "rename" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Existing source field to rename or move", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip when source field is missing", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting the target field if it already exists", + "type": "boolean" + }, + "to": { + "description": "New field name or destination path", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Set processor - Assign a literal or copied value to a field (mutually exclusive inputs)", + "properties": { + "action": { + "enum": [ + "set" + ], + "type": "string" + }, + "copy_from": { + "description": "Copy value from another field instead of providing a literal", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting an existing target field", + "type": "boolean" + }, + "to": { + "description": "Target field to set or create", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Literal value to assign to the target field" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Append processor - Append one or more values to an existing or new array field", + "properties": { + "action": { + "enum": [ + "append" + ], + "type": "string" + }, + "allow_duplicates": { + "description": "If true, do not deduplicate appended values", + "type": "boolean" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "to": { + "description": "Array field to append values to", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Values to append (must be literal, no templates)", + "items": {}, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove by prefix processor - Remove a field and all nested fields matching the prefix", + "properties": { + "action": { + "enum": [ + "remove_by_prefix" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove along with all its nested fields", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove processor - Delete one or more fields from the document", + "properties": { + "action": { + "enum": [ + "remove" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove from the document", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "replace" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "pattern": { + "description": "A non-empty string or string with whitespace.", + "minLength": 1, + "type": "string" + }, + "replacement": { + "type": "string" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern", + "replacement" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "uppercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "lowercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "trim" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "join" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "delimiter": { + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "delimiter", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Convert processor - Change the data type of a field value (integer, long, double, boolean, or string)", + "properties": { + "action": { + "enum": [ + "convert" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to convert to a different data type", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "to": { + "description": "Target field for the converted value (defaults to source)", + "minLength": 1, + "type": "string" + }, + "type": { + "description": "Target data type: integer, long, double, boolean, or string", + "enum": [ + "integer", + "long", + "double", + "boolean", + "string" + ], + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "concat" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "field" + ], + "type": "string" + }, + "value": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "literal" + ], + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + } + ] + }, + "minItems": 1, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Manual ingest pipeline wrapper around native Elasticsearch processors", + "properties": { + "action": { + "description": "Manual ingest pipeline - executes raw Elasticsearch ingest processors", + "enum": [ + "manual_ingest_pipeline" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "on_failure": { + "description": "Fallback processors to run when a processor fails", + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "processors": { + "description": "List of raw Elasticsearch ingest processors to run", + "items": { + "additionalProperties": false, + "properties": { + "append": {}, + "attachment": {}, + "bytes": {}, + "circle": {}, + "community_id": {}, + "convert": {}, + "csv": {}, + "date": {}, + "date_index_name": {}, + "dissect": {}, + "dot_expander": {}, + "drop": {}, + "enrich": {}, + "fail": {}, + "fingerprint": {}, + "foreach": {}, + "geo_grid": {}, + "geoip": {}, + "grok": {}, + "gsub": {}, + "html_strip": {}, + "inference": {}, + "ip_location": {}, + "join": {}, + "json": {}, + "kv": {}, + "lowercase": {}, + "network_direction": {}, + "pipeline": {}, + "redact": {}, + "registered_domain": {}, + "remove": {}, + "rename": {}, + "reroute": {}, + "script": {}, + "set": {}, + "set_security_user": {}, + "sort": {}, + "split": {}, + "terminate": {}, + "trim": {}, + "uppercase": {}, + "uri_parts": {}, + "urldecode": {}, + "user_agent": {} + }, + "required": [ + "append", + "attachment", + "bytes", + "circle", + "community_id", + "convert", + "csv", + "date", + "date_index_name", + "dissect", + "dot_expander", + "drop", + "enrich", + "fail", + "fingerprint", + "foreach", + "ip_location", + "geo_grid", + "geoip", + "grok", + "gsub", + "html_strip", + "inference", + "join", + "json", + "kv", + "lowercase", + "network_direction", + "pipeline", + "redact", + "registered_domain", + "remove", + "rename", + "reroute", + "script", + "set", + "set_security_user", + "sort", + "split", + "terminate", + "trim", + "uppercase", + "urldecode", + "uri_parts", + "user_agent" + ], + "type": "object" + }, + "type": "array" + }, + "tag": { + "description": "Optional ingest processor tag for Elasticsearch", + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "processors" + ], + "type": "object" + } + ] + }, + { + "additionalProperties": false, + "properties": { + "condition": { + "allOf": [ + { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + { + "properties": { + "steps": { + "items": {}, + "type": "array" + } + }, + "required": [ + "steps" + ], + "type": "object" + } + ] + }, + "customIdentifier": { + "type": "string" + } + }, + "required": [ + "condition" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "updated_at": { + "not": {} + } + }, + "required": [ + "steps" + ], + "type": "object" + }, + "settings": { + "additionalProperties": false, + "properties": { + "index.number_of_replicas": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.number_of_shards": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.refresh_interval": { + "additionalProperties": false, + "properties": { + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + -1 + ], + "type": "number" + } + ] + } + }, + "required": [ + "value" + ], + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "lifecycle", + "processing", + "settings", + "failure_store" + ], + "type": "object" + }, + { + "properties": { + "wired": { + "additionalProperties": false, + "properties": { + "fields": { + "additionalProperties": { + "allOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + }, + "type": "array" + }, + { + "items": {}, + "type": "array" + }, + {} + ] + }, + "type": "object" + }, + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "format": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": { + "enum": [ + "keyword", + "match_only_text", + "long", + "double", + "date", + "boolean", + "ip", + "geo_point" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ] + } + ] + }, + "type": "object" + }, + "routing": { + "items": { + "additionalProperties": false, + "properties": { + "destination": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "status": { + "enum": [ + "enabled", + "disabled" + ], + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + } + }, + "required": [ + "destination", + "where" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "fields", + "routing" + ], + "type": "object" + } + }, + "required": [ + "wired" + ], + "type": "object" + } + ] + }, + { + "allOf": [ + { + "properties": { + "failure_store": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + }, + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "enabled": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "enabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "lifecycle": { + "additionalProperties": false, + "properties": { + "disabled": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "disabled" + ], + "type": "object" + } + }, + "required": [ + "lifecycle" + ], + "type": "object" + } + ] + } + ] + }, + "lifecycle": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "dsl": { + "additionalProperties": false, + "properties": { + "data_retention": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "dsl" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "ilm": { + "additionalProperties": false, + "properties": { + "policy": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "policy" + ], + "type": "object" + } + }, + "required": [ + "ilm" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "inherit": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "inherit" + ], + "type": "object" + } + ] + }, + "processing": { + "additionalProperties": false, + "properties": { + "steps": { + "items": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "Grok processor - Extract fields from text using grok patterns", + "properties": { + "action": { + "enum": [ + "grok" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with grok patterns", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern_definitions": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "patterns": { + "description": "Grok patterns applied in order to extract fields", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "patterns" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Dissect processor - Extract fields from text using a lightweight, delimiter-based parser", + "properties": { + "action": { + "enum": [ + "dissect" + ], + "type": "string" + }, + "append_separator": { + "description": "Separator inserted when target fields are concatenated", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to parse with dissect pattern", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "pattern": { + "description": "Dissect pattern describing field boundaries", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Date processor - Parse dates from strings using one or more expected formats", + "properties": { + "action": { + "enum": [ + "date" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "formats": { + "description": "Accepted input date formats, tried in order", + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "from": { + "description": "Source field containing the date/time text", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "locale": { + "description": "Optional locale for date parsing", + "minLength": 1, + "type": "string" + }, + "output_format": { + "description": "Optional output format for storing the parsed date as text", + "minLength": 1, + "type": "string" + }, + "timezone": { + "description": "Optional timezone for date parsing", + "minLength": 1, + "type": "string" + }, + "to": { + "description": "Target field for the parsed date (defaults to source)", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "formats" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "drop_document" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "math" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "expression": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "expression", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Rename processor - Change a field name and optionally its location", + "properties": { + "action": { + "enum": [ + "rename" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Existing source field to rename or move", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip when source field is missing", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting the target field if it already exists", + "type": "boolean" + }, + "to": { + "description": "New field name or destination path", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Set processor - Assign a literal or copied value to a field (mutually exclusive inputs)", + "properties": { + "action": { + "enum": [ + "set" + ], + "type": "string" + }, + "copy_from": { + "description": "Copy value from another field instead of providing a literal", + "minLength": 1, + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "override": { + "description": "Allow overwriting an existing target field", + "type": "boolean" + }, + "to": { + "description": "Target field to set or create", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Literal value to assign to the target field" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Append processor - Append one or more values to an existing or new array field", + "properties": { + "action": { + "enum": [ + "append" + ], + "type": "string" + }, + "allow_duplicates": { + "description": "If true, do not deduplicate appended values", + "type": "boolean" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "to": { + "description": "Array field to append values to", + "minLength": 1, + "type": "string" + }, + "value": { + "description": "Values to append (must be literal, no templates)", + "items": {}, + "minItems": 1, + "type": "array" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "to", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove by prefix processor - Remove a field and all nested fields matching the prefix", + "properties": { + "action": { + "enum": [ + "remove_by_prefix" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove along with all its nested fields", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Remove processor - Delete one or more fields from the document", + "properties": { + "action": { + "enum": [ + "remove" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Field to remove from the document", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "replace" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "pattern": { + "description": "A non-empty string or string with whitespace.", + "minLength": 1, + "type": "string" + }, + "replacement": { + "type": "string" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "pattern", + "replacement" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "uppercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "lowercase" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "trim" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "join" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "delimiter": { + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "delimiter", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Convert processor - Change the data type of a field value (integer, long, double, boolean, or string)", + "properties": { + "action": { + "enum": [ + "convert" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "description": "Source field to convert to a different data type", + "minLength": 1, + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "description": "Skip processing when source field is missing", + "type": "boolean" + }, + "to": { + "description": "Target field for the converted value (defaults to source)", + "minLength": 1, + "type": "string" + }, + "type": { + "description": "Target data type: integer, long, double, boolean, or string", + "enum": [ + "integer", + "long", + "double", + "boolean", + "string" + ], + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Base processor options plus conditional execution", + "properties": { + "action": { + "enum": [ + "concat" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "from": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "field" + ], + "type": "string" + }, + "value": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "literal" + ], + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + } + ] + }, + "minItems": 1, + "type": "array" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "ignore_missing": { + "type": "boolean" + }, + "to": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Manual ingest pipeline wrapper around native Elasticsearch processors", + "properties": { + "action": { + "description": "Manual ingest pipeline - executes raw Elasticsearch ingest processors", + "enum": [ + "manual_ingest_pipeline" + ], + "type": "string" + }, + "customIdentifier": { + "description": "Custom identifier to correlate this processor across outputs", + "minLength": 1, + "type": "string" + }, + "description": { + "description": "Human-readable notes about this processor step", + "type": "string" + }, + "ignore_failure": { + "description": "Continue pipeline execution if this processor fails", + "type": "boolean" + }, + "on_failure": { + "description": "Fallback processors to run when a processor fails", + "items": { + "additionalProperties": {}, + "type": "object" + }, + "type": "array" + }, + "processors": { + "description": "List of raw Elasticsearch ingest processors to run", + "items": { + "additionalProperties": false, + "properties": { + "append": {}, + "attachment": {}, + "bytes": {}, + "circle": {}, + "community_id": {}, + "convert": {}, + "csv": {}, + "date": {}, + "date_index_name": {}, + "dissect": {}, + "dot_expander": {}, + "drop": {}, + "enrich": {}, + "fail": {}, + "fingerprint": {}, + "foreach": {}, + "geo_grid": {}, + "geoip": {}, + "grok": {}, + "gsub": {}, + "html_strip": {}, + "inference": {}, + "ip_location": {}, + "join": {}, + "json": {}, + "kv": {}, + "lowercase": {}, + "network_direction": {}, + "pipeline": {}, + "redact": {}, + "registered_domain": {}, + "remove": {}, + "rename": {}, + "reroute": {}, + "script": {}, + "set": {}, + "set_security_user": {}, + "sort": {}, + "split": {}, + "terminate": {}, + "trim": {}, + "uppercase": {}, + "uri_parts": {}, + "urldecode": {}, + "user_agent": {} + }, + "required": [ + "append", + "attachment", + "bytes", + "circle", + "community_id", + "convert", + "csv", + "date", + "date_index_name", + "dissect", + "dot_expander", + "drop", + "enrich", + "fail", + "fingerprint", + "foreach", + "ip_location", + "geo_grid", + "geoip", + "grok", + "gsub", + "html_strip", + "inference", + "join", + "json", + "kv", + "lowercase", + "network_direction", + "pipeline", + "redact", + "registered_domain", + "remove", + "rename", + "reroute", + "script", + "set", + "set_security_user", + "sort", + "split", + "terminate", + "trim", + "uppercase", + "urldecode", + "uri_parts", + "user_agent" + ], + "type": "object" + }, + "type": "array" + }, + "tag": { + "description": "Optional ingest processor tag for Elasticsearch", + "type": "string" + }, + "where": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "Conditional expression controlling whether this processor runs" + } + }, + "required": [ + "action", + "processors" + ], + "type": "object" + } + ] + }, + { + "additionalProperties": false, + "properties": { + "condition": { + "allOf": [ + { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + { + "properties": { + "steps": { + "items": {}, + "type": "array" + } + }, + "required": [ + "steps" + ], + "type": "object" + } + ] + }, + "customIdentifier": { + "type": "string" + } + }, + "required": [ + "condition" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "updated_at": { + "not": {} + } + }, + "required": [ + "steps" + ], + "type": "object" + }, + "settings": { + "additionalProperties": false, + "properties": { + "index.number_of_replicas": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.number_of_shards": { + "additionalProperties": false, + "properties": { + "value": { + "type": "number" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "index.refresh_interval": { + "additionalProperties": false, + "properties": { + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "enum": [ + -1 + ], + "type": "number" + } + ] + } + }, + "required": [ + "value" + ], + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "lifecycle", + "processing", + "settings", + "failure_store" + ], + "type": "object" + }, + { + "properties": { + "classic": { + "additionalProperties": false, + "properties": { + "field_overrides": { + "additionalProperties": { + "allOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + }, + { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + }, + "type": "array" + }, + { + "items": {}, + "type": "array" + }, + {} + ] + }, + "type": "object" + }, + { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "format": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": { + "enum": [ + "keyword", + "match_only_text", + "long", + "double", + "date", + "boolean", + "ip", + "geo_point" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ] + } + ] + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "classic" + ], + "type": "object" + } + ] + } + ] + } + }, + "required": [ + "ingest" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Update ingest stream settings", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/{name}/content/export": { + "post": { + "description": "Exports the content associated to a stream.

[Required authorization] Route required privileges: manage_stream.", + "operationId": "post-streams-name-content-export", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "include": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "objects": { + "additionalProperties": false, + "properties": { + "all": { + "additionalProperties": false, + "properties": {}, + "type": "object" + } + }, + "required": [ + "all" + ], + "type": "object" + } + }, + "required": [ + "objects" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "objects": { + "additionalProperties": false, + "properties": { + "mappings": { + "type": "boolean" + }, + "queries": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + }, + "routing": { + "items": { + "allOf": [ + {}, + { + "properties": { + "destination": { + "type": "string" + } + }, + "required": [ + "destination" + ], + "type": "object" + } + ] + }, + "type": "array" + } + }, + "required": [ + "mappings", + "queries", + "routing" + ], + "type": "object" + } + }, + "required": [ + "objects" + ], + "type": "object" + } + ] + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "description", + "version", + "include" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Export stream content", + "tags": [ + "streams" + ] + } + }, + "/api/streams/{name}/content/import": { + "post": { + "description": "Links content objects to a stream.

[Required authorization] Route required privileges: manage_stream.", + "operationId": "post-streams-name-content-import", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "additionalProperties": false, + "properties": { + "content": {}, + "include": { + "type": "string" + } + }, + "required": [ + "include", + "content" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Import content into a stream", + "tags": [ + "streams" + ] + } + }, + "/api/streams/{name}/queries": { + "get": { + "description": "Fetches all queries linked to a stream that are visible to the current user in the current space.

[Required authorization] Route required privileges: read_stream.", + "operationId": "get-streams-name-queries", + "parameters": [ + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": {}, + "summary": "Get stream queries", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/{name}/queries/_bulk": { + "post": { + "description": "Bulk update queries of a stream. Can add new queries and delete existing ones.

[Required authorization] Route required privileges: manage_stream.", + "operationId": "post-streams-name-queries-bulk", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "operations": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "index": { + "allOf": [ + { + "properties": { + "id": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "title": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "id", + "title" + ], + "type": "object" + }, + { + "properties": { + "evidence": { + "items": { + "type": "string" + }, + "type": "array" + }, + "feature": { + "additionalProperties": false, + "properties": { + "filter": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + "name": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "name", + "filter", + "type" + ], + "type": "object" + }, + "kql": { + "additionalProperties": false, + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "severity_score": { + "type": "number" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + ] + } + }, + "required": [ + "index" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "delete": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + } + }, + "required": [ + "delete" + ], + "type": "object" + } + ] + }, + "type": "array" + } + }, + "required": [ + "operations" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Bulk update queries", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/{name}/queries/{queryId}": { + "delete": { + "description": "Remove a query from a stream. Noop if the query is not found on the stream.

[Required authorization] Route required privileges: manage_stream.", + "operationId": "delete-streams-name-queries-queryid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "queryId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": {}, + "summary": "Remove a query from a stream", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + }, + "put": { + "description": "Adds a query to a stream. Noop if the query is already present on the stream.

[Required authorization] Route required privileges: manage_stream.", + "operationId": "put-streams-name-queries-queryid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "queryId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "evidence": { + "items": { + "type": "string" + }, + "type": "array" + }, + "feature": { + "additionalProperties": false, + "properties": { + "filter": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + "name": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + }, + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "name", + "filter", + "type" + ], + "type": "object" + }, + "kql": { + "additionalProperties": false, + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "severity_score": { + "type": "number" + }, + "title": { + "description": "A non-empty string.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "title", + "kql" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Upsert a query to a stream", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/{name}/significant_events": { + "get": { + "description": "Read the significant events

[Required authorization] Route required privileges: read_stream.", + "operationId": "get-streams-name-significant-events", + "parameters": [ + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "from", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "bucketSize", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Query string to filter significant events on metadata fields", + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": {}, + "summary": "Read the significant events", + "tags": [ + "streams" + ], + "x-state": "Technical Preview; added in 9.1.0" + } + }, + "/api/streams/{name}/significant_events/_generate": { + "post": { + "description": "Generate significant events queries based on the stream data

[Required authorization] Route required privileges: read_stream.", + "operationId": "post-streams-name-significant-events-generate", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Optional connector ID. If not provided, the default AI connector from settings will be used.", + "in": "query", + "name": "connectorId", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "from", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Number of sample documents to use for generation from the current data of stream", + "in": "query", + "name": "sampleDocsSize", + "required": false, + "schema": { + "type": "number" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "system": { + "additionalProperties": false, + "properties": { + "description": { + "type": "string" + }, + "filter": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + "name": { + "type": "string" + }, + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "type", + "name", + "description", + "filter" + ], + "type": "object" + } + }, + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Generate significant events", + "tags": [ + "streams" + ], + "x-state": "Technical Preview; added in 9.2.0" + } + }, + "/api/streams/{name}/significant_events/_preview": { + "post": { + "description": "Preview significant event results based on a given query

[Required authorization] Route required privileges: read_stream.", + "operationId": "post-streams-name-significant-events-preview", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "from", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "bucketSize", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": false, + "properties": { + "query": { + "additionalProperties": false, + "properties": { + "feature": { + "additionalProperties": false, + "properties": { + "filter": { + "anyOf": [ + { + "anyOf": [ + { + "additionalProperties": false, + "description": "A condition that compares a field to a value or range using an operator as the key.", + "properties": { + "contains": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Contains comparison value." + }, + "endsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Ends-with comparison value." + }, + "eq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Equality comparison value." + }, + "field": { + "description": "The document field to filter on.", + "minLength": 1, + "type": "string" + }, + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than comparison value." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Greater-than-or-equal comparison value." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than comparison value." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Less-than-or-equal comparison value." + }, + "neq": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Inequality comparison value." + }, + "range": { + "additionalProperties": false, + "description": "Range comparison values.", + "properties": { + "gt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "gte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lt": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + }, + "lte": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "A value that can be a string, number, or boolean." + } + }, + "type": "object" + }, + "startsWith": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + } + ], + "description": "Starts-with comparison value." + } + }, + "required": [ + "field" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that checks for the existence or non-existence of a field.", + "properties": { + "exists": { + "description": "Indicates whether the field exists or not.", + "type": "boolean" + }, + "field": { + "description": "The document field to check.", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "field" + ], + "type": "object" + } + ], + "description": "A basic filter condition, either unary or binary." + }, + { + "additionalProperties": false, + "description": "A logical AND that groups multiple conditions.", + "properties": { + "and": { + "description": "An array of conditions. All sub-conditions must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "and" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical OR that groups multiple conditions.", + "properties": { + "or": { + "description": "An array of conditions. At least one sub-condition must be true for this condition to be true.", + "items": {}, + "type": "array" + } + }, + "required": [ + "or" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A logical NOT that negates a condition.", + "properties": { + "not": { + "description": "A condition that negates another condition." + } + }, + "required": [ + "not" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to false.", + "properties": { + "never": { + "additionalProperties": false, + "description": "An empty object. This condition never matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "never" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "A condition that always evaluates to true. Useful for catch-all scenarios, but use with caution as partitions are ordered.", + "properties": { + "always": { + "additionalProperties": false, + "description": "An empty object. This condition always matches.", + "properties": {}, + "type": "object" + } + }, + "required": [ + "always" + ], + "type": "object" + } + ], + "description": "The root condition object. It can be a simple filter or a combination of other conditions." + }, + "name": { + "type": "string" + }, + "type": { + "enum": [ + "system" + ], + "type": "string" + } + }, + "required": [ + "name", + "filter", + "type" + ], + "type": "object" + }, + "kql": { + "additionalProperties": false, + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "required": [ + "kql" + ], + "type": "object" + } + }, + "required": [ + "query" + ], + "type": "object" + } + } + } + }, + "responses": {}, + "summary": "Preview significant events", + "tags": [ + "streams" + ], + "x-state": "Technical Preview; added in 9.1.0" + } + }, + "/api/streams/{streamName}/attachments": { + "get": { + "description": "Fetches all attachments linked to a stream that are visible to the current user in the current space. Optionally filter by attachment types, search query, and tags.

[Required authorization] Route required privileges: read_stream.", + "operationId": "get-streams-streamname-attachments", + "parameters": [ + { + "description": "The name of the stream", + "in": "path", + "name": "streamName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Search query to filter attachments by title", + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Filter by attachment types (single value or array)", + "in": "query", + "name": "attachmentTypes", + "required": false, + "schema": { + "anyOf": [ + { + "enum": [ + "dashboard", + "rule", + "slo" + ], + "type": "string" + }, + { + "items": { + "enum": [ + "dashboard", + "rule", + "slo" + ], + "type": "string" + }, + "type": "array" + } + ] + } + }, + { + "description": "Filter by tags (single value or array)", + "in": "query", + "name": "tags", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "listAttachmentsExample": { + "value": {} + } + }, + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "listAttachmentsResponse": { + "value": { + "attachments": [ + { + "createdAt": "2023-02-23T16:15:47.275Z", + "description": "Dashboard for monitoring production services", + "id": "dashboard-123", + "streamNames": [ + "logs.awsfirehose", + "logs.nginx" + ], + "tags": [ + "monitoring", + "production" + ], + "title": "My Dashboard", + "type": "dashboard", + "updatedAt": "2023-03-24T14:39:17.636Z" + } + ] + } + } + } + } + }, + "description": "Successfully retrieved attachments" + } + }, + "summary": "Get stream attachments", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/{streamName}/attachments/_bulk": { + "post": { + "description": "Bulk update attachments linked to a stream. Can link new attachments and delete existing ones. Supports mixed attachment types in a single request.

[Required authorization] Route required privileges: manage_stream.", + "operationId": "post-streams-streamname-attachments-bulk", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The name of the stream", + "in": "path", + "name": "streamName", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "bulkAttachmentsExample": { + "value": { + "operations": [ + { + "index": { + "id": "dashboard-123", + "type": "dashboard" + } + }, + { + "delete": { + "id": "rule-456", + "type": "rule" + } + } + ] + } + } + }, + "schema": { + "additionalProperties": false, + "properties": { + "operations": { + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "index": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "type": { + "enum": [ + "dashboard", + "rule", + "slo" + ], + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + } + }, + "required": [ + "index" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "delete": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "type": { + "enum": [ + "dashboard", + "rule", + "slo" + ], + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + } + }, + "required": [ + "delete" + ], + "type": "object" + } + ] + }, + "type": "array" + } + }, + "required": [ + "operations" + ], + "type": "object" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "bulkAttachmentsResponse": { + "value": { + "acknowledged": true + } + } + } + } + }, + "description": "Successfully performed bulk operations" + } + }, + "summary": "Bulk update attachments", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + }, + "/api/streams/{streamName}/attachments/{attachmentType}/{attachmentId}": { + "delete": { + "description": "Unlinks an attachment from a stream. Noop if the attachment is not linked to the stream.

[Required authorization] Route required privileges: manage_stream.", + "operationId": "delete-streams-streamname-attachments-attachmenttype-attachmentid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The name of the stream", + "in": "path", + "name": "streamName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "The type of the attachment", + "in": "path", + "name": "attachmentType", + "required": true, + "schema": { + "enum": [ + "dashboard", + "rule", + "slo" + ], + "type": "string" + } + }, + { + "description": "The ID of the attachment", + "in": "path", + "name": "attachmentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "unlinkAttachmentExample": { + "value": {} + } + }, + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "unlinkAttachmentResponse": { + "value": { + "acknowledged": true + } + } + } + } + }, + "description": "Successfully unlinked attachment" + } + }, + "summary": "Unlink an attachment from a stream", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + }, + "put": { + "description": "Links an attachment to a stream. Noop if the attachment is already linked to the stream.

[Required authorization] Route required privileges: manage_stream.", + "operationId": "put-streams-streamname-attachments-attachmenttype-attachmentid", + "parameters": [ + { + "description": "A required header to protect against CSRF attacks", + "in": "header", + "name": "kbn-xsrf", + "required": true, + "schema": { + "example": "true", + "type": "string" + } + }, + { + "description": "The name of the stream", + "in": "path", + "name": "streamName", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "The type of the attachment", + "in": "path", + "name": "attachmentType", + "required": true, + "schema": { + "enum": [ + "dashboard", + "rule", + "slo" + ], + "type": "string" + } + }, + { + "description": "The ID of the attachment", + "in": "path", + "name": "attachmentId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "linkAttachmentExample": { + "value": {} + } + }, + "schema": { + "anyOf": [ + { + "additionalProperties": false, + "properties": {}, + "type": "object" + }, + { + "enum": [ + "null" + ], + "nullable": true + }, + { + "not": {} + } + ] + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "linkAttachmentResponse": { + "value": { + "acknowledged": true + } + } + } + } + }, + "description": "Successfully linked attachment" + } + }, + "summary": "Link an attachment to a stream", + "tags": [ + "streams" + ], + "x-state": "Technical Preview" + } + } + }, "security": [ { "basicAuth": [] @@ -29,5 +103229,90 @@ "url": "http://localhost:5622" } ], - "tags": [] + "tags": [ + { + "name": "agent builder" + }, + { + "name": "alerting" + }, + { + "name": "connectors" + }, + { + "name": "Data streams" + }, + { + "name": "Elastic Agent actions" + }, + { + "name": "Elastic Agent binary download sources" + }, + { + "name": "Elastic Agent policies" + }, + { + "name": "Elastic Agent status" + }, + { + "name": "Elastic Agents" + }, + { + "name": "Elastic Package Manager (EPM)" + }, + { + "name": "Fleet agentless policies" + }, + { + "name": "Fleet cloud connectors" + }, + { + "name": "Fleet enrollment API keys" + }, + { + "name": "Fleet internals" + }, + { + "name": "Fleet outputs" + }, + { + "name": "Fleet package policies" + }, + { + "name": "Fleet proxies" + }, + { + "name": "Fleet remote synced integrations" + }, + { + "name": "Fleet Server hosts" + }, + { + "name": "Fleet service tokens" + }, + { + "name": "Fleet uninstall tokens" + }, + { + "name": "maintenance-window" + }, + { + "name": "Message Signing Service" + }, + { + "name": "roles" + }, + { + "name": "saved objects" + }, + { + "name": "spaces" + }, + { + "name": "streams" + }, + { + "name": "system" + } + ] } \ No newline at end of file From 8004a960dfe7ee8454169635991347d5105d78c2 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Wed, 4 Feb 2026 10:51:06 +0100 Subject: [PATCH 44/49] Regenerate oas_docs bundles --- oas_docs/bundle.json | 50 +++++++++++++++++++++++++++++++++ oas_docs/bundle.serverless.json | 50 +++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json index 18a6084b79ae4..b1830059909e9 100644 --- a/oas_docs/bundle.json +++ b/oas_docs/bundle.json @@ -382,6 +382,56 @@ }, "openapi": "3.0.0", "paths": { + "/api/actions/connector/_oauth_callback": { + "get": { + "operationId": "get-actions-connector-oauth-callback", + "parameters": [ + { + "in": "query", + "name": "code", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "state", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "error", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "error_description", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "session_state", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": {}, + "summary": "", + "tags": [] + } + }, "/api/actions/connector/{id}": { "delete": { "description": "WARNING: When you delete a connector, it cannot be recovered.", diff --git a/oas_docs/bundle.serverless.json b/oas_docs/bundle.serverless.json index 87a19fbd7e200..c7a649562cb0b 100644 --- a/oas_docs/bundle.serverless.json +++ b/oas_docs/bundle.serverless.json @@ -382,6 +382,56 @@ }, "openapi": "3.0.0", "paths": { + "/api/actions/connector/_oauth_callback": { + "get": { + "operationId": "get-actions-connector-oauth-callback", + "parameters": [ + { + "in": "query", + "name": "code", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "state", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "error", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "error_description", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "session_state", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": {}, + "summary": "", + "tags": [] + } + }, "/api/actions/connector/{id}": { "delete": { "description": "WARNING: When you delete a connector, it cannot be recovered.", From a792b5bf4abb98d1e66a9a20e4d9cf7695980f85 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 4 Feb 2026 10:06:24 +0000 Subject: [PATCH 45/49] Changes from make api-docs --- oas_docs/output/kibana.serverless.yaml | 41 ++++++++++++++++++++++++++ oas_docs/output/kibana.yaml | 41 ++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/oas_docs/output/kibana.serverless.yaml b/oas_docs/output/kibana.serverless.yaml index df4d07e138467..867fe3d578c65 100644 --- a/oas_docs/output/kibana.serverless.yaml +++ b/oas_docs/output/kibana.serverless.yaml @@ -410,6 +410,47 @@ paths: x-metaTags: - content: Kibana, Elastic Cloud Serverless name: product_name + /api/actions/connector/_oauth_callback: + get: + operationId: get-actions-connector-oauth-callback + parameters: + - in: query + name: code + required: false + schema: + type: string + - in: query + name: state + required: false + schema: + type: string + - in: query + name: error + required: false + schema: + type: string + - in: query + name: error_description + required: false + schema: + type: string + - in: query + name: session_state + required: false + schema: + type: string + responses: {} + summary: '' + tags: [] + x-metaTags: + - content: Kibana, Elastic Cloud Serverless + name: product_name + description: |- + **Spaces method and path for this operation:** + +
get /s/{space_id}/api/actions/connector/_oauth_callback
+ + Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information. /api/actions/connector/{id}: delete: description: |- diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index e1412e4e6a284..a7b376f037ce1 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -481,6 +481,47 @@ paths: x-metaTags: - content: Kibana name: product_name + /api/actions/connector/_oauth_callback: + get: + operationId: get-actions-connector-oauth-callback + parameters: + - in: query + name: code + required: false + schema: + type: string + - in: query + name: state + required: false + schema: + type: string + - in: query + name: error + required: false + schema: + type: string + - in: query + name: error_description + required: false + schema: + type: string + - in: query + name: session_state + required: false + schema: + type: string + responses: {} + summary: '' + tags: [] + x-metaTags: + - content: Kibana + name: product_name + description: |- + **Spaces method and path for this operation:** + +
get /s/{space_id}/api/actions/connector/_oauth_callback
+ + Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information. /api/actions/connector/{id}: delete: description: |- From 977af7323b1c17a627d46c8247c21cf27e7c28df Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Wed, 4 Feb 2026 11:36:51 +0100 Subject: [PATCH 46/49] Fix SO tests --- .../__fixtures__/connector_token/10.2.0.json | 22 +++++++++++++++++++ .../server-internal/src/object_types/index.ts | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 packages/kbn-check-saved-objects-cli/src/migrations/__fixtures__/connector_token/10.2.0.json diff --git a/packages/kbn-check-saved-objects-cli/src/migrations/__fixtures__/connector_token/10.2.0.json b/packages/kbn-check-saved-objects-cli/src/migrations/__fixtures__/connector_token/10.2.0.json new file mode 100644 index 0000000000000..3ffe9305f6591 --- /dev/null +++ b/packages/kbn-check-saved-objects-cli/src/migrations/__fixtures__/connector_token/10.2.0.json @@ -0,0 +1,22 @@ +{ + "10.1.0": [ + { + "connectorId": "abc123-def456-connector-id", + "tokenType": "access_token", + "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRlc3QgVXNlciIsImlhdCI6MTUxNjIzOTAyMn0.test_signature", + "expiresAt": "2025-01-15T14:30:00.000Z", + "createdAt": "2025-01-15T13:00:00.000Z", + "updatedAt": "2025-01-15T13:00:00.000Z" + } + ], + "10.2.0": [ + { + "connectorId": "abc123-def456-connector-id", + "tokenType": "access_token", + "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRlc3QgVXNlciIsImlhdCI6MTUxNjIzOTAyMn0.test_signature", + "expiresAt": "2025-01-15T14:30:00.000Z", + "createdAt": "2025-01-15T13:00:00.000Z", + "updatedAt": "2025-01-15T13:00:00.000Z" + } + ] +} diff --git a/src/core/packages/saved-objects/server-internal/src/object_types/index.ts b/src/core/packages/saved-objects/server-internal/src/object_types/index.ts index a9f3af4f604ce..ce0041b74ed52 100644 --- a/src/core/packages/saved-objects/server-internal/src/object_types/index.ts +++ b/src/core/packages/saved-objects/server-internal/src/object_types/index.ts @@ -11,4 +11,4 @@ export { registerCoreObjectTypes } from './registration'; // set minimum number of registered saved objects to ensure no object types are removed after 8.8 // declared in internal implementation explicitly to prevent unintended changes. -export const SAVED_OBJECT_TYPES_COUNT = 145 as const; +export const SAVED_OBJECT_TYPES_COUNT = 146 as const; From 2218c08a8eacec581ac5fbab335093cfc77cada6 Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Wed, 4 Feb 2026 11:51:39 +0100 Subject: [PATCH 47/49] Update docs and regenerate bundles --- oas_docs/bundle.json | 24 ++++- oas_docs/bundle.serverless.json | 24 ++++- .../actions/server/routes/oauth_callback.ts | 87 +++++++++++++++++-- 3 files changed, 121 insertions(+), 14 deletions(-) diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json index b1830059909e9..2aefb204530bb 100644 --- a/oas_docs/bundle.json +++ b/oas_docs/bundle.json @@ -384,9 +384,11 @@ "paths": { "/api/actions/connector/_oauth_callback": { "get": { + "description": "Handles the OAuth 2.0 authorization code callback from external providers. Exchanges the authorization code for access and refresh tokens.", "operationId": "get-actions-connector-oauth-callback", "parameters": [ { + "description": "The authorization code returned by the OAuth provider.", "in": "query", "name": "code", "required": false, @@ -395,6 +397,7 @@ } }, { + "description": "The state parameter for CSRF protection.", "in": "query", "name": "state", "required": false, @@ -403,6 +406,7 @@ } }, { + "description": "Error code if the authorization failed.", "in": "query", "name": "error", "required": false, @@ -411,6 +415,7 @@ } }, { + "description": "Human-readable error description.", "in": "query", "name": "error_description", "required": false, @@ -419,6 +424,7 @@ } }, { + "description": "Session state from the OAuth provider (e.g., Microsoft).", "in": "query", "name": "session_state", "required": false, @@ -427,9 +433,21 @@ } } ], - "responses": {}, - "summary": "", - "tags": [] + "responses": { + "200": { + "description": "Returns an HTML page with error details if authorization fails." + }, + "302": { + "description": "Redirects to Kibana on successful authorization." + }, + "401": { + "description": "User is not authenticated." + } + }, + "summary": "Handle OAuth callback", + "tags": [ + "connectors" + ] } }, "/api/actions/connector/{id}": { diff --git a/oas_docs/bundle.serverless.json b/oas_docs/bundle.serverless.json index c7a649562cb0b..3bd182ed4f50d 100644 --- a/oas_docs/bundle.serverless.json +++ b/oas_docs/bundle.serverless.json @@ -384,9 +384,11 @@ "paths": { "/api/actions/connector/_oauth_callback": { "get": { + "description": "Handles the OAuth 2.0 authorization code callback from external providers. Exchanges the authorization code for access and refresh tokens.", "operationId": "get-actions-connector-oauth-callback", "parameters": [ { + "description": "The authorization code returned by the OAuth provider.", "in": "query", "name": "code", "required": false, @@ -395,6 +397,7 @@ } }, { + "description": "The state parameter for CSRF protection.", "in": "query", "name": "state", "required": false, @@ -403,6 +406,7 @@ } }, { + "description": "Error code if the authorization failed.", "in": "query", "name": "error", "required": false, @@ -411,6 +415,7 @@ } }, { + "description": "Human-readable error description.", "in": "query", "name": "error_description", "required": false, @@ -419,6 +424,7 @@ } }, { + "description": "Session state from the OAuth provider (e.g., Microsoft).", "in": "query", "name": "session_state", "required": false, @@ -427,9 +433,21 @@ } } ], - "responses": {}, - "summary": "", - "tags": [] + "responses": { + "200": { + "description": "Returns an HTML page with error details if authorization fails." + }, + "302": { + "description": "Redirects to Kibana on successful authorization." + }, + "401": { + "description": "User is not authenticated." + } + }, + "summary": "Handle OAuth callback", + "tags": [ + "connectors" + ] } }, "/api/actions/connector/{id}": { diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index cbd1822bd5e2f..e5d603eb98017 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import type { CoreSetup, IRouter, Logger } from '@kbn/core/server'; +import { i18n } from '@kbn/i18n'; import startCase from 'lodash/startCase'; import type { ActionsPluginsStart } from '../plugin'; import type { ILicenseState } from '../lib'; @@ -21,11 +22,54 @@ import { ConnectorTokenClient } from '../lib/connector_token_client'; import type { OAuthRateLimiter } from '../lib/oauth_rate_limiter'; const querySchema = schema.object({ - code: schema.maybe(schema.string()), - state: schema.maybe(schema.string()), - error: schema.maybe(schema.string()), - error_description: schema.maybe(schema.string()), - session_state: schema.maybe(schema.string()), // Microsoft OAuth includes this + code: schema.maybe( + schema.string({ + meta: { + description: i18n.translate('xpack.actions.oauthCallback.codeParamDescription', { + defaultMessage: 'The authorization code returned by the OAuth provider.', + }), + }, + }) + ), + state: schema.maybe( + schema.string({ + meta: { + description: i18n.translate('xpack.actions.oauthCallback.stateParamDescription', { + defaultMessage: 'The state parameter for CSRF protection.', + }), + }, + }) + ), + error: schema.maybe( + schema.string({ + meta: { + description: i18n.translate('xpack.actions.oauthCallback.errorParamDescription', { + defaultMessage: 'Error code if the authorization failed.', + }), + }, + }) + ), + error_description: schema.maybe( + schema.string({ + meta: { + description: i18n.translate( + 'xpack.actions.oauthCallback.errorDescriptionParamDescription', + { + defaultMessage: 'Human-readable error description.', + } + ), + }, + }) + ), + session_state: schema.maybe( + schema.string({ + meta: { + description: i18n.translate('xpack.actions.oauthCallback.sessionStateParamDescription', { + defaultMessage: 'Session state from the OAuth provider (e.g., Microsoft).', + }), + }, + }) + ), }); interface OAuthConnectorSecrets { @@ -177,14 +221,41 @@ export const oauthCallbackRoute = ( { path: `${BASE_ACTION_API_PATH}/connector/_oauth_callback`, security: DEFAULT_ACTION_ROUTE_SECURITY, - validate: { - query: querySchema, - }, options: { access: 'public', + summary: i18n.translate('xpack.actions.oauthCallback.routeSummary', { + defaultMessage: 'Handle OAuth callback', + }), + description: i18n.translate('xpack.actions.oauthCallback.routeDescription', { + defaultMessage: + 'Handles the OAuth 2.0 authorization code callback from external providers. Exchanges the authorization code for access and refresh tokens.', + }), + tags: ['oas-tag:connectors'], // authRequired: true is the default - user must have valid session // The OAuth redirect happens in their browser, so they will have their session cookie }, + validate: { + request: { + query: querySchema, + }, + response: { + 302: { + description: i18n.translate('xpack.actions.oauthCallback.response302Description', { + defaultMessage: 'Redirects to Kibana on successful authorization.', + }), + }, + 200: { + description: i18n.translate('xpack.actions.oauthCallback.response200Description', { + defaultMessage: 'Returns an HTML page with error details if authorization fails.', + }), + }, + 401: { + description: i18n.translate('xpack.actions.oauthCallback.response401Description', { + defaultMessage: 'User is not authenticated.', + }), + }, + }, + }, }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { From 19c1f9404eb491b580c5d0a5115956417502ef31 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 4 Feb 2026 11:06:18 +0000 Subject: [PATCH 48/49] Changes from make api-docs --- oas_docs/output/kibana.serverless.yaml | 42 +++++++++++++++++--------- oas_docs/output/kibana.yaml | 42 +++++++++++++++++--------- 2 files changed, 56 insertions(+), 28 deletions(-) diff --git a/oas_docs/output/kibana.serverless.yaml b/oas_docs/output/kibana.serverless.yaml index 867fe3d578c65..55646cc4f01b3 100644 --- a/oas_docs/output/kibana.serverless.yaml +++ b/oas_docs/output/kibana.serverless.yaml @@ -412,45 +412,59 @@ paths: name: product_name /api/actions/connector/_oauth_callback: get: + description: |- + **Spaces method and path for this operation:** + +
get /s/{space_id}/api/actions/connector/_oauth_callback
+ + Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information. + + Handles the OAuth 2.0 authorization code callback from external providers. Exchanges the authorization code for access and refresh tokens. operationId: get-actions-connector-oauth-callback parameters: - - in: query + - description: The authorization code returned by the OAuth provider. + in: query name: code required: false schema: type: string - - in: query + - description: The state parameter for CSRF protection. + in: query name: state required: false schema: type: string - - in: query + - description: Error code if the authorization failed. + in: query name: error required: false schema: type: string - - in: query + - description: Human-readable error description. + in: query name: error_description required: false schema: type: string - - in: query + - description: Session state from the OAuth provider (e.g., Microsoft). + in: query name: session_state required: false schema: type: string - responses: {} - summary: '' - tags: [] + responses: + '200': + description: Returns an HTML page with error details if authorization fails. + '302': + description: Redirects to Kibana on successful authorization. + '401': + description: User is not authenticated. + summary: Handle OAuth callback + tags: + - connectors x-metaTags: - content: Kibana, Elastic Cloud Serverless name: product_name - description: |- - **Spaces method and path for this operation:** - -
get /s/{space_id}/api/actions/connector/_oauth_callback
- - Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information. /api/actions/connector/{id}: delete: description: |- diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index a7b376f037ce1..b54e0ec44d3b3 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -483,45 +483,59 @@ paths: name: product_name /api/actions/connector/_oauth_callback: get: + description: |- + **Spaces method and path for this operation:** + +
get /s/{space_id}/api/actions/connector/_oauth_callback
+ + Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information. + + Handles the OAuth 2.0 authorization code callback from external providers. Exchanges the authorization code for access and refresh tokens. operationId: get-actions-connector-oauth-callback parameters: - - in: query + - description: The authorization code returned by the OAuth provider. + in: query name: code required: false schema: type: string - - in: query + - description: The state parameter for CSRF protection. + in: query name: state required: false schema: type: string - - in: query + - description: Error code if the authorization failed. + in: query name: error required: false schema: type: string - - in: query + - description: Human-readable error description. + in: query name: error_description required: false schema: type: string - - in: query + - description: Session state from the OAuth provider (e.g., Microsoft). + in: query name: session_state required: false schema: type: string - responses: {} - summary: '' - tags: [] + responses: + '200': + description: Returns an HTML page with error details if authorization fails. + '302': + description: Redirects to Kibana on successful authorization. + '401': + description: User is not authenticated. + summary: Handle OAuth callback + tags: + - connectors x-metaTags: - content: Kibana name: product_name - description: |- - **Spaces method and path for this operation:** - -
get /s/{space_id}/api/actions/connector/_oauth_callback
- - Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information. /api/actions/connector/{id}: delete: description: |- From f79a2b30df21e3da7b235bcdeb746194d7185d7c Mon Sep 17 00:00:00 2001 From: Lorena Balan Date: Wed, 4 Feb 2026 14:17:12 +0100 Subject: [PATCH 49/49] Fix tests and remove token normalization --- .../registration/type_registrations.test.ts | 1 + .../shared/actions/server/config.test.ts | 40 +++++++++++++++++++ ...t_oauth_authorization_code_access_token.ts | 6 +-- ...t_oauth_client_credentials_access_token.ts | 6 +-- .../server/lib/get_oauth_jwt_access_token.ts | 6 +-- .../actions/server/routes/oauth_callback.ts | 6 +-- .../check_registered_task_types.ts | 1 + 7 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/core/server/integration_tests/saved_objects/registration/type_registrations.test.ts b/src/core/server/integration_tests/saved_objects/registration/type_registrations.test.ts index 47495cb8709a2..40774601b27c0 100644 --- a/src/core/server/integration_tests/saved_objects/registration/type_registrations.test.ts +++ b/src/core/server/integration_tests/saved_objects/registration/type_registrations.test.ts @@ -121,6 +121,7 @@ const previouslyRegisteredTypes = [ 'ml-module', 'ml-telemetry', 'monitoring-telemetry', + 'oauth_state', 'observability-onboarding-state', 'osquery-pack', 'osquery-pack-asset', diff --git a/x-pack/platform/plugins/shared/actions/server/config.test.ts b/x-pack/platform/plugins/shared/actions/server/config.test.ts index a376702a660c5..88dbe0acc502f 100644 --- a/x-pack/platform/plugins/shared/actions/server/config.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/config.test.ts @@ -35,6 +35,16 @@ describe('config validation', () => { "microsoftExchangeUrl": "https://login.microsoftonline.com", "microsoftGraphApiScope": "https://graph.microsoft.com/.default", "microsoftGraphApiUrl": "https://graph.microsoft.com/v1.0", + "oAuthRateLimit": Object { + "authorize": Object { + "limit": 100, + "lookbackWindow": "1h", + }, + "callback": Object { + "limit": 100, + "lookbackWindow": "1h", + }, + }, "preconfigured": Object {}, "preconfiguredAlertHistoryEsIndex": false, "responseTimeout": "PT1M", @@ -69,6 +79,16 @@ describe('config validation', () => { "microsoftExchangeUrl": "https://login.microsoftonline.com", "microsoftGraphApiScope": "https://graph.microsoft.com/.default", "microsoftGraphApiUrl": "https://graph.microsoft.com/v1.0", + "oAuthRateLimit": Object { + "authorize": Object { + "limit": 100, + "lookbackWindow": "1h", + }, + "callback": Object { + "limit": 100, + "lookbackWindow": "1h", + }, + }, "preconfigured": Object { "mySlack1": Object { "actionTypeId": ".slack", @@ -212,6 +232,16 @@ describe('config validation', () => { "microsoftExchangeUrl": "https://login.microsoftonline.com", "microsoftGraphApiScope": "https://graph.microsoft.com/.default", "microsoftGraphApiUrl": "https://graph.microsoft.com/v1.0", + "oAuthRateLimit": Object { + "authorize": Object { + "limit": 100, + "lookbackWindow": "1h", + }, + "callback": Object { + "limit": 100, + "lookbackWindow": "1h", + }, + }, "preconfigured": Object {}, "preconfiguredAlertHistoryEsIndex": false, "responseTimeout": "PT1M", @@ -382,6 +412,16 @@ describe('config validation', () => { "microsoftExchangeUrl": "https://login.microsoftonline.com", "microsoftGraphApiScope": "https://graph.microsoft.com/.default", "microsoftGraphApiUrl": "https://graph.microsoft.com/v1.0", + "oAuthRateLimit": Object { + "authorize": Object { + "limit": 100, + "lookbackWindow": "1h", + }, + "callback": Object { + "limit": 100, + "lookbackWindow": "1h", + }, + }, "preconfigured": Object {}, "preconfiguredAlertHistoryEsIndex": false, "rateLimiter": Object { diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts index 37fce49c2009b..ff2b8d3a7eb41 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_authorization_code_access_token.ts @@ -5,7 +5,6 @@ * 2.0. */ -import startCase from 'lodash/startCase'; import pLimit from 'p-limit'; import type { Logger } from '@kbn/core/server'; import type { ActionsConfigurationUtilities } from '../actions_config'; @@ -143,10 +142,7 @@ export const getOAuthAuthorizationCodeAccessToken = async ({ shouldUseBasicAuth ); - // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, - // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") - const normalizedTokenType = startCase(tokenResult.tokenType); - const newAccessToken = `${normalizedTokenType} ${tokenResult.accessToken}`; + const newAccessToken = `${tokenResult.tokenType} ${tokenResult.accessToken}`; // Update stored token await connectorTokenClient.updateWithRefreshToken({ diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts index 35512e0113d81..8452b7ef9d53e 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_client_credentials_access_token.ts @@ -5,7 +5,6 @@ * 2.0. */ import type { Logger } from '@kbn/core/server'; -import startCase from 'lodash/startCase'; import type { ActionsConfigurationUtilities } from '../actions_config'; import type { ConnectorToken, ConnectorTokenClientContract } from '../types'; import { requestOAuthClientCredentialsToken } from './request_oauth_client_credentials_token'; @@ -80,10 +79,7 @@ export const getOAuthClientCredentialsAccessToken = async ({ }, configurationUtilities ); - // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, - // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") - const normalizedTokenType = startCase(tokenResult.tokenType); - accessToken = `${normalizedTokenType} ${tokenResult.accessToken}`; + accessToken = `${tokenResult.tokenType} ${tokenResult.accessToken}`; // try to update connector_token SO if (connectorId && connectorTokenClient) { diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts index 9d8a939f17c68..20f0b21933f27 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_oauth_jwt_access_token.ts @@ -5,7 +5,6 @@ * 2.0. */ import type { Logger } from '@kbn/core/server'; -import startCase from 'lodash/startCase'; import type { ActionsConfigurationUtilities } from '../actions_config'; import type { ConnectorToken, ConnectorTokenClientContract } from '../types'; import { createJWTAssertion } from './create_jwt_assertion'; @@ -90,10 +89,7 @@ export const getOAuthJwtAccessToken = async ({ logger, configurationUtilities ); - // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, - // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") - const normalizedTokenType = startCase(tokenResult.tokenType); - accessToken = `${normalizedTokenType} ${tokenResult.accessToken}`; + accessToken = `${tokenResult.tokenType} ${tokenResult.accessToken}`; // try to update connector_token SO if (connectorId && connectorTokenClient) { diff --git a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts index e5d603eb98017..2413e2cda293b 100644 --- a/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts +++ b/x-pack/platform/plugins/shared/actions/server/routes/oauth_callback.ts @@ -8,7 +8,6 @@ import { schema } from '@kbn/config-schema'; import type { CoreSetup, IRouter, Logger } from '@kbn/core/server'; import { i18n } from '@kbn/i18n'; -import startCase from 'lodash/startCase'; import type { ActionsPluginsStart } from '../plugin'; import type { ILicenseState } from '../lib'; import { BASE_ACTION_API_PATH } from '../../common'; @@ -396,10 +395,7 @@ export const oauthCallbackRoute = ( connectorId: oauthState.connectorId, tokenType: 'access_token', }); - // Some providers return "bearer" instead of "Bearer", but expect "Bearer" in the header, - // so we normalize the token type, i.e., capitalize first letter (e.g., "bearer" -> "Bearer") - const normalizedTokenType = startCase(tokenResult.tokenType); - const formattedToken = `${normalizedTokenType} ${tokenResult.accessToken}`; + const formattedToken = `${tokenResult.tokenType} ${tokenResult.accessToken}`; await connectorTokenClient.createWithRefreshToken({ connectorId: oauthState.connectorId, accessToken: formattedToken, diff --git a/x-pack/platform/test/plugin_api_integration/test_suites/task_manager/check_registered_task_types.ts b/x-pack/platform/test/plugin_api_integration/test_suites/task_manager/check_registered_task_types.ts index 37c4fa0de0b7b..697da0cd627de 100644 --- a/x-pack/platform/test/plugin_api_integration/test_suites/task_manager/check_registered_task_types.ts +++ b/x-pack/platform/test/plugin_api_integration/test_suites/task_manager/check_registered_task_types.ts @@ -105,6 +105,7 @@ export default function ({ getService }: FtrProviderContext) { 'actions:.xmatters', 'actions:.xsoar', 'actions:connector_usage_reporting', + 'actions:oauth_state_cleanup', 'actions_telemetry', 'ad_hoc_run-backfill', 'alert-deletion',