diff --git a/src/platform/packages/shared/kbn-connector-specs/README.md b/src/platform/packages/shared/kbn-connector-specs/README.md index 36453c8d4def8..b1a7ad3b7dbca 100644 --- a/src/platform/packages/shared/kbn-connector-specs/README.md +++ b/src/platform/packages/shared/kbn-connector-specs/README.md @@ -57,7 +57,12 @@ export const MyConnector: SingleFileConnectorDefinition = { supportedFeatureIds: ['workflows'], }, - authTypes: ['bearer'], + auth: { + types: ['bearer'], + headers: { + 'Content-Type': 'application/json', + } + }, schema: z.object({ url: z.string().url().describe('API URL'), @@ -155,17 +160,23 @@ are specified, defaults to no authentication. Can also specify a custom schema f which will be used in place of the default ```typescript -authTypes: [ - // use basic auth type with the default schema - 'basic', - // use api_key_header auth type with a custom header field - { - type: 'api_key_header', - defaults: { - headerField: 'custom-api-key-field' +auth: { + types: [ + // use basic auth type with the default schema + 'basic', + // use api_key_header auth type with a custom header field + { + type: 'api_key_header', + defaults: { + headerField: 'custom-api-key-field' + } } + ], + // optionally add headers that will be added to all requests + headers: { + 'Content-Type': 'application/json', } -] +} ``` ### Schema diff --git a/src/platform/packages/shared/kbn-connector-specs/src/connector_spec.ts b/src/platform/packages/shared/kbn-connector-specs/src/connector_spec.ts index e451b9d3d9150..3712c0f93b835 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/connector_spec.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/connector_spec.ts @@ -24,7 +24,7 @@ import type { z } from '@kbn/zod/v4'; import type { Logger } from '@kbn/logging'; import type { LicenseType } from '@kbn/licensing-types'; -import type { AxiosInstance } from 'axios'; +import type { AxiosHeaderValue, AxiosInstance } from 'axios'; export { UISchemas } from './connector_spec_ui'; @@ -239,7 +239,10 @@ export interface AuthTypeDef { export interface ConnectorSpec { metadata: ConnectorMetadata; - authTypes?: Array; + auth?: { + types: Array; + headers?: Record; + }; // Single unified schema for all connector fields (config + secrets) // Mark sensitive fields with withUIMeta({ sensitive: true }) diff --git a/src/platform/packages/shared/kbn-connector-specs/src/lib/generate_secrets_schema_from_spec.test.ts b/src/platform/packages/shared/kbn-connector-specs/src/lib/generate_secrets_schema_from_spec.test.ts index 01f90ba3870ba..8f6b543872e23 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/lib/generate_secrets_schema_from_spec.test.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/lib/generate_secrets_schema_from_spec.test.ts @@ -12,23 +12,28 @@ import { generateSecretsSchemaFromSpec } from './generate_secrets_schema_from_sp describe('generateSecretsSchemaFromSpec', () => { test('correctly generates schemas for array of auth types', () => { - const schema = generateSecretsSchemaFromSpec([ - 'none', - 'basic', - 'bearer', - 'oauth_client_credentials', - { - type: 'api_key_header', - defaults: { - headerField: 'custom-api-key-field', + const schema = generateSecretsSchemaFromSpec({ + types: [ + 'none', + 'basic', + 'bearer', + 'oauth_client_credentials', + { + type: 'api_key_header', + defaults: { + headerField: 'custom-api-key-field', + }, }, + ], + headers: { + 'X-Custom-Header': 'CustomValue', }, - ]); + }); expect(z.toJSONSchema(schema)).toMatchSnapshot(); }); test('returns empty object schema when no auth types are provided', () => { - const schema = generateSecretsSchemaFromSpec([]); + const schema = generateSecretsSchemaFromSpec({ types: [] }); expect(z.toJSONSchema(schema)).toMatchSnapshot(); }); }); diff --git a/src/platform/packages/shared/kbn-connector-specs/src/lib/generate_secrets_schema_from_spec.ts b/src/platform/packages/shared/kbn-connector-specs/src/lib/generate_secrets_schema_from_spec.ts index f910a8729c53b..8d6a70f76a262 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/lib/generate_secrets_schema_from_spec.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/lib/generate_secrets_schema_from_spec.ts @@ -11,9 +11,9 @@ import { z } from '@kbn/zod/v4'; import type { ConnectorSpec } from '../connector_spec'; import { getSchemaForAuthType } from '.'; -export const generateSecretsSchemaFromSpec = (authTypes: ConnectorSpec['authTypes']) => { +export const generateSecretsSchemaFromSpec = (authSpec: ConnectorSpec['auth']) => { const secretSchemas: z.core.$ZodTypeDiscriminable[] = []; - for (const authType of authTypes || []) { + for (const authType of authSpec?.types || []) { secretSchemas.push(getSchemaForAuthType(authType)); } return secretSchemas.length > 0 diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/abuseipdb.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/abuseipdb.ts index 21363b056e1cb..7615b222baa3c 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/abuseipdb.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/abuseipdb.ts @@ -31,14 +31,9 @@ export const AbuseIPDBConnector: ConnectorSpec = { supportedFeatureIds: ['workflows'], }, - authTypes: [ - { - type: 'api_key_header', - defaults: { - headerField: 'Key', - }, - }, - ], + auth: { + types: [{ type: 'api_key_header', defaults: { headerField: 'Key' } }], + }, actions: { checkIp: { diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/alienvault_otx.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/alienvault_otx.ts index 3e678895c3733..f480b5f7f728f 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/alienvault_otx.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/alienvault_otx.ts @@ -31,14 +31,9 @@ export const AlienVaultOTXConnector: ConnectorSpec = { supportedFeatureIds: ['workflows'], }, - authTypes: [ - { - type: 'api_key_header', - defaults: { - headerField: 'X-OTX-API-KEY', - }, - }, - ], + auth: { + types: [{ type: 'api_key_header', defaults: { headerField: 'X-OTX-API-KEY' } }], + }, actions: { getIndicator: { diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/greynoise.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/greynoise.ts index 3241c953e86d9..2f3c218950556 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/greynoise.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/greynoise.ts @@ -31,14 +31,9 @@ export const GreyNoiseConnector: ConnectorSpec = { supportedFeatureIds: ['workflows'], }, - authTypes: [ - { - type: 'api_key_header', - defaults: { - headerField: 'key', - }, - }, - ], + auth: { + types: [{ type: 'api_key_header', defaults: { headerField: 'key' } }], + }, actions: { getIpContext: { diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/shodan.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/shodan.ts index f806447122b87..77147caf9369c 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/shodan.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/shodan.ts @@ -31,14 +31,9 @@ export const ShodanConnector: ConnectorSpec = { supportedFeatureIds: ['workflows'], }, - authTypes: [ - { - type: 'api_key_header', - defaults: { - headerField: 'X-Api-Key', - }, - }, - ], + auth: { + types: [{ type: 'api_key_header', defaults: { headerField: 'X-Api-Key' } }], + }, actions: { searchHosts: { diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/urlvoid.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/urlvoid.ts index d494b3ba7b2c6..cbb05a2463f50 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/urlvoid.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/urlvoid.ts @@ -32,14 +32,9 @@ export const URLVoidConnector: ConnectorSpec = { supportedFeatureIds: ['workflows'], }, - authTypes: [ - { - type: 'api_key_header', - defaults: { - headerField: 'X-Api-Key', - }, - }, - ], + auth: { + types: [{ type: 'api_key_header', defaults: { headerField: 'X-Api-Key' } }], + }, actions: { scanDomain: { diff --git a/src/platform/packages/shared/kbn-connector-specs/src/specs/virustotal.ts b/src/platform/packages/shared/kbn-connector-specs/src/specs/virustotal.ts index 2ea461afb7777..80f21375b197c 100644 --- a/src/platform/packages/shared/kbn-connector-specs/src/specs/virustotal.ts +++ b/src/platform/packages/shared/kbn-connector-specs/src/specs/virustotal.ts @@ -31,19 +31,15 @@ export const VirusTotalConnector: ConnectorSpec = { supportedFeatureIds: ['workflows'], }, - authTypes: [ - { - type: 'api_key_header', - defaults: { - headerField: 'x-apikey', + auth: { + types: [ + { + type: 'api_key_header', + defaults: { headerField: 'x-apikey' }, + overrides: { meta: { 'x-apikey': { placeholder: 'vt-...' } } }, }, - overrides: { - meta: { - 'x-apikey': { placeholder: 'vt-...' }, - }, - }, - }, - ], + ], + }, actions: { scanFileHash: { diff --git a/x-pack/platform/plugins/shared/actions/server/lib/action_executor.test.ts b/x-pack/platform/plugins/shared/actions/server/lib/action_executor.test.ts index 18bb81718dc89..fd16d4e304ebc 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/action_executor.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/action_executor.test.ts @@ -128,6 +128,22 @@ const connectorType: jest.Mocked = { executor: jest.fn(), }; +const connectorTypeWithGlobalHeaders: jest.Mocked = { + id: 'test-with-global-headers', + name: 'Test with Global Headers', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: z.object({ bar: z.boolean() }) }, + secrets: { schema: z.object({ baz: z.boolean() }) }, + params: { schema: z.object({ foo: z.boolean() }) }, + }, + executor: jest.fn(), + globalAuthHeaders: { + 'x-custom-header': 'custom-header-value', + }, +}; + const systemConnectorType: jest.Mocked = { id: '.cases', name: 'Cases', @@ -354,6 +370,38 @@ describe('Action Executor', () => { expect(mockRateLimiterLog).toBeCalledWith('test'); }); + test(`successfully ${label} with any defined auth headers`, async () => { + mockGetRequestBodyByte.mockReturnValue(300); + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce( + connectorSavedObject + ); + connectorTypeRegistry.get.mockReturnValueOnce(connectorTypeWithGlobalHeaders); + + if (executeUnsecure) { + await actionExecutor.executeUnsecured(executeUnsecuredParams); + } else { + await actionExecutor.execute(executeParams); + } + + expect(connectorTypeWithGlobalHeaders.executor).toHaveBeenCalledWith({ + actionId: CONNECTOR_ID, + services: expect.anything(), + config: { + bar: true, + }, + secrets: { + baz: true, + }, + params: { foo: true }, + logger: loggerMock, + connectorUsageCollector: expect.any(ConnectorUsageCollector), + globalAuthHeaders: { + 'x-custom-header': 'custom-header-value', + }, + ...(executeUnsecure ? {} : { source: SOURCE }), + }); + }); + for (const executionSource of [ { name: `http`, diff --git a/x-pack/platform/plugins/shared/actions/server/lib/action_executor.ts b/x-pack/platform/plugins/shared/actions/server/lib/action_executor.ts index e2805e697e179..3e76de928ce74 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/action_executor.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/action_executor.ts @@ -535,6 +535,7 @@ export class ActionExecutor { config: validatedConfig, secrets: validatedSecrets, taskInfo, + globalAuthHeaders: actionType.globalAuthHeaders, configurationUtilities, logger, source, diff --git a/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.test.ts b/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.test.ts index 6fec11f57e4b8..d7fedf5ea3b32 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.test.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/get_axios_instance.test.ts @@ -149,6 +149,77 @@ describe('getAxiosInstance', () => { expect(getCustomAgents).toHaveBeenCalledWith(configurationUtilities, logger, 'http://test3'); }); + test('returns axios instance configured for api_key_header auth and additional headers', async () => { + const getAxios = getAxiosInstanceWithAuth({ + authTypeRegistry, + configurationUtilities, + logger, + }); + const result = await getAxios({ + additionalHeaders: { + 'X-Custom-Header': 'i-am-a-custom-header-string', + 'X-Version': '1.0.0', + }, + connectorId: '1', + secrets: { + authType: 'api_key_header', + 'X-Custom-Auth': 'i-am-a-custom-auth-string', + }, + }); + + expect(result).not.toBeUndefined(); + expect(result!.defaults.auth).toBeUndefined(); + expect(result!.defaults.headers.common).toEqual( + expect.objectContaining({ + 'X-Custom-Header': 'i-am-a-custom-header-string', + 'X-Version': '1.0.0', + 'X-Custom-Auth': 'i-am-a-custom-auth-string', + }) + ); + + // @ts-expect-error + expect(result!.interceptors.request.handlers.length).toBe(1); + + // @ts-expect-error + const result2 = result!.interceptors.request.handlers[0].fulfilled({ url: 'http://test3' }); + expect(getCustomAgents).toHaveBeenCalledWith(configurationUtilities, logger, 'http://test3'); + }); + + test('auth type configured headers take precedence over additional headers', async () => { + const getAxios = getAxiosInstanceWithAuth({ + authTypeRegistry, + configurationUtilities, + logger, + }); + const result = await getAxios({ + additionalHeaders: { + 'X-Custom-Auth': 'place-holder-value', + 'X-Version': '1.0.0', + }, + connectorId: '1', + secrets: { + authType: 'api_key_header', + 'X-Custom-Auth': 'i-am-a-custom-auth-string', + }, + }); + + expect(result).not.toBeUndefined(); + expect(result!.defaults.auth).toBeUndefined(); + expect(result!.defaults.headers.common).toEqual( + expect.objectContaining({ + 'X-Version': '1.0.0', + 'X-Custom-Auth': 'i-am-a-custom-auth-string', + }) + ); + + // @ts-expect-error + expect(result!.interceptors.request.handlers.length).toBe(1); + + // @ts-expect-error + const result2 = result!.interceptors.request.handlers[0].fulfilled({ url: 'http://test3' }); + expect(getCustomAgents).toHaveBeenCalledWith(configurationUtilities, logger, 'http://test3'); + }); + test('returns axios instance configured for oauth client credentials auth when connector token client is undefined', async () => { (requestOAuthClientCredentialsToken as jest.Mock).mockResolvedValueOnce({ tokenType: 'Bearer', 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 749e9f3a5935f..f9ea72d273f6d 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 @@ -5,7 +5,7 @@ * 2.0. */ -import type { AxiosInstance } from 'axios'; +import type { AxiosHeaderValue, AxiosInstance } from 'axios'; import axios from 'axios'; import type { Logger } from '@kbn/core/server'; import type { GetTokenOpts } from '@kbn/connector-specs'; @@ -29,6 +29,7 @@ interface GetAxiosInstanceOpts { type ValidatedSecrets = Record; export interface GetAxiosInstanceWithAuthFnOpts { + additionalHeaders?: Record; connectorId: string; connectorTokenClient?: ConnectorTokenClientContract; secrets: ValidatedSecrets; @@ -41,7 +42,12 @@ export const getAxiosInstanceWithAuth = ({ configurationUtilities, logger, }: GetAxiosInstanceOpts): GetAxiosInstanceWithAuthFn => { - return async ({ connectorId, secrets, connectorTokenClient }: GetAxiosInstanceWithAuthFnOpts) => { + return async ({ + additionalHeaders, + connectorId, + secrets, + connectorTokenClient, + }: GetAxiosInstanceWithAuthFnOpts) => { let authTypeId: string | undefined; try { authTypeId = (secrets as { authType?: string }).authType || 'none'; @@ -59,6 +65,13 @@ export const getAxiosInstanceWithAuth = ({ beforeRedirect: getBeforeRedirectFn(configurationUtilities), }); + // add any additional headers that should be included in every request + if (additionalHeaders) { + Object.keys(additionalHeaders).forEach((key) => { + axiosInstance.defaults.headers.common[key] = additionalHeaders[key]; + }); + } + // create a request interceptor to inject custom http/https agents based on the URL axiosInstance.interceptors.request.use((config) => { if (config.url) { diff --git a/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/create_connector_from_spec.ts b/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/create_connector_from_spec.ts index 270c1ff80b3d9..9e487ef139f9d 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/create_connector_from_spec.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/create_connector_from_spec.ts @@ -36,9 +36,10 @@ export const createConnectorTypeFromSpec = ( supportedFeatureIds: spec.metadata.supportedFeatureIds, validate: { config: generateConfigSchema(spec.schema), - secrets: generateSecretsSchema(spec.authTypes), + secrets: generateSecretsSchema(spec.auth), params: generateParamsSchema(spec.actions), }, executor, + globalAuthHeaders: spec.auth?.headers, }; }; 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 404d91e90a86a..2405c4cd9312b 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 @@ -41,6 +41,7 @@ export const generateExecutorFunction = ({ actionId: connectorId, config, connectorTokenClient, + globalAuthHeaders, params, secrets, logger, @@ -49,8 +50,9 @@ export const generateExecutorFunction = ({ const axiosInstance = await getAxiosInstanceWithAuth({ connectorId, - secrets, connectorTokenClient, + additionalHeaders: globalAuthHeaders, + secrets, }); if (!actions[subAction]) { diff --git a/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/generate_secrets_schema.ts b/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/generate_secrets_schema.ts index 30078fda60e67..68ddd33d09db7 100644 --- a/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/generate_secrets_schema.ts +++ b/x-pack/platform/plugins/shared/actions/server/lib/single_file_connectors/generate_secrets_schema.ts @@ -11,9 +11,9 @@ import { generateSecretsSchemaFromSpec } from '@kbn/connector-specs/src/lib'; import type { ActionTypeSecrets, ValidatorType } from '../../types'; export const generateSecretsSchema = ( - authTypes: ConnectorSpec['authTypes'] + authSpec: ConnectorSpec['auth'] ): ValidatorType => { return { - schema: generateSecretsSchemaFromSpec(authTypes), + schema: generateSecretsSchemaFromSpec(authSpec), }; }; diff --git a/x-pack/platform/plugins/shared/actions/server/types.ts b/x-pack/platform/plugins/shared/actions/server/types.ts index 35bc76044598f..ca43f1c0c4091 100644 --- a/x-pack/platform/plugins/shared/actions/server/types.ts +++ b/x-pack/platform/plugins/shared/actions/server/types.ts @@ -19,6 +19,7 @@ import type { ISavedObjectsRepository, IScopedClusterClient, } from '@kbn/core/server'; +import type { AxiosHeaderValue } from 'axios'; import type { SubActionConnector } from './sub_action_framework/sub_action_connector'; import type { ServiceParams } from './sub_action_framework/types'; import type { ActionTypeRegistry } from './action_type_registry'; @@ -88,6 +89,7 @@ export interface ActionTypeExecutorOptions< secrets: Secrets; params: Params; logger: Logger; + globalAuthHeaders?: Record; taskInfo?: TaskInfo; configurationUtilities: ActionsConfigurationUtilities; source?: ActionExecutionSource; @@ -215,6 +217,8 @@ export interface ActionType< params?: Params; source?: ActionExecutionSourceType; }) => string[]; + // Headers that should be added to every Axios request made by this action type + globalAuthHeaders?: Record; renderParameterTemplates?: RenderParameterTemplates; executor: ExecutorType; getService?: (params: ServiceParams) => SubActionConnector; diff --git a/x-pack/platform/plugins/shared/stack_connectors/public/connector_types_from_spec/generate_schema.test.ts b/x-pack/platform/plugins/shared/stack_connectors/public/connector_types_from_spec/generate_schema.test.ts index 0b36766d18c67..77f9b100c516d 100644 --- a/x-pack/platform/plugins/shared/stack_connectors/public/connector_types_from_spec/generate_schema.test.ts +++ b/x-pack/platform/plugins/shared/stack_connectors/public/connector_types_from_spec/generate_schema.test.ts @@ -15,15 +15,17 @@ describe('generateSchema', () => { schema: z4.object({ url: z4.string().min(1), }), - authTypes: [ - 'basic', - { - type: 'api_key_header', - defaults: { - headerField: 'custom-api-key-field', + auth: { + types: [ + 'basic', + { + type: 'api_key_header', + defaults: { + headerField: 'custom-api-key-field', + }, }, - }, - ], + ], + }, } as unknown as ConnectorSpec); expect(z4.toJSONSchema(schema)).toMatchSnapshot(); diff --git a/x-pack/platform/plugins/shared/stack_connectors/public/connector_types_from_spec/generate_schema.ts b/x-pack/platform/plugins/shared/stack_connectors/public/connector_types_from_spec/generate_schema.ts index e14698137f70c..718d96d58968e 100644 --- a/x-pack/platform/plugins/shared/stack_connectors/public/connector_types_from_spec/generate_schema.ts +++ b/x-pack/platform/plugins/shared/stack_connectors/public/connector_types_from_spec/generate_schema.ts @@ -12,6 +12,6 @@ import { generateSecretsSchemaFromSpec } from '@kbn/connector-specs/src/lib'; export const generateSchema = (spec: ConnectorSpec) => { return z.object({ config: spec.schema ?? z.object({}), - secrets: generateSecretsSchemaFromSpec(spec.authTypes), + secrets: generateSecretsSchemaFromSpec(spec.auth), }); }; diff --git a/x-pack/platform/test/alerting_api_integration/common/plugins/actions_simulators/server/test_spec_connector.ts b/x-pack/platform/test/alerting_api_integration/common/plugins/actions_simulators/server/test_spec_connector.ts index c8ade9a0b8140..affaa1c31f490 100644 --- a/x-pack/platform/test/alerting_api_integration/common/plugins/actions_simulators/server/test_spec_connector.ts +++ b/x-pack/platform/test/alerting_api_integration/common/plugins/actions_simulators/server/test_spec_connector.ts @@ -17,16 +17,22 @@ export const TestSingleFileConnector: ConnectorSpec = { supportedFeatureIds: ['workflows'], }, - authTypes: [ - 'none', - 'basic', - { - type: 'api_key_header', - defaults: { - headerField: 'Key', + auth: { + types: [ + 'none', + 'basic', + { + type: 'api_key_header', + defaults: { + headerField: 'Key', + }, }, + ], + headers: { + 'x-test-header': 'i-am-a-test-header-value', + 'kbn-xsrf': 'foo', }, - ], + }, schema: z.object({ apiUrl: z.string().describe('API URL'), diff --git a/x-pack/platform/test/alerting_api_integration/spaces_only/tests/actions/single_file_connector_types/execute.ts b/x-pack/platform/test/alerting_api_integration/spaces_only/tests/actions/single_file_connector_types/execute.ts index da3212a48f9f6..d96a288b4fd70 100644 --- a/x-pack/platform/test/alerting_api_integration/spaces_only/tests/actions/single_file_connector_types/execute.ts +++ b/x-pack/platform/test/alerting_api_integration/spaces_only/tests/actions/single_file_connector_types/execute.ts @@ -208,6 +208,8 @@ export default function createSingleFileConnectorTest({ getService }: FtrProvide .expect(200); expect(response.body.data.key).to.eql(key); + expect(response.body.data['x-test-header']).to.eql('i-am-a-test-header-value'); + expect(response.body.data['kbn-xsrf']).to.eql('foo'); }); }); });