Skip to content

Commit

Permalink
[Response Ops][Actions] Adding configuration to override default MS G…
Browse files Browse the repository at this point in the history
…raph API Scope and Exchange URL values (#175812)

Resolves #166064

## Summary

Adds the following configurations to the `kibana.yml` config:
* `xpack.actions.microsoftGraphApiScope` - overrides the default Graph
API scope value of `https://graph.microsoft.com/.default`
* `xpack.actions.microsoftExchangeUrl` - overrides the default value of
`https://login.microsoftonline.com`

This allows users in different Azure environments to customize their
endpoints as needed.

## To Verify

We are unable to test this in a different environment but we can verify
that the config overrides the defaults as expected by setting the config
values to something different and the logging out the params that are
sent to `getOAuthClientCredentialsAccessToken` in
`x-pack/plugins/stack_connectors/server/connector_types/email/send_email.ts`.
Then create an MS Exchange email connector and test it to see that the
logged values are overridden as expected.

---------

Co-authored-by: Kibana Machine <[email protected]>
(cherry picked from commit f7e4f7a)
  • Loading branch information
ymao1 committed Feb 1, 2024
1 parent 3457f32 commit 0313a19
Show file tree
Hide file tree
Showing 16 changed files with 205 additions and 23 deletions.
9 changes: 9 additions & 0 deletions docs/settings/alert-action-settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@ A list of action types that are enabled. It defaults to `["*"]`, enabling all ty
+
Disabled action types will not appear as an option when creating new connectors, but existing connectors and actions of that type will remain in {kib} and will not function.

`xpack.actions.microsoftExchangeUrl`::
The URL for the Microsoft Azure Active Directory endpoint to use for MS Exchange email authentication. Default: `https://login.microsoftonline.com`.

`xpack.actions.microsoftGraphApiUrl`::
The URL for the Microsoft Graph API endpoint to use for MS Exchange email authentication. Default: `https://graph.microsoft.com/v1.0`.

`xpack.actions.microsoftGraphApiScope`::
The URL for the Microsoft Graph API scope endpoint to use for MS Exchange email authentication. Default: `https://graph.microsoft.com/.default`.

`xpack.actions.proxyUrl` {ess-icon}::
Specifies the proxy URL to use, if using a proxy for actions. By default, no proxy is used.
+
Expand Down
4 changes: 4 additions & 0 deletions x-pack/plugins/actions/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ export * from './execution_log_types';
export const BASE_ACTION_API_PATH = '/api/actions';
export const INTERNAL_BASE_ACTION_API_PATH = '/internal/actions';
export const ACTIONS_FEATURE_ID = 'actions';

export const DEFAULT_MICROSOFT_EXCHANGE_URL = 'https://login.microsoftonline.com';
export const DEFAULT_MICROSOFT_GRAPH_API_URL = 'https://graph.microsoft.com/v1.0';
export const DEFAULT_MICROSOFT_GRAPH_API_SCOPE = 'https://graph.microsoft.com/.default';
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
import { schema } from '@kbn/config-schema';
import moment from 'moment';
import { ByteSizeValue } from '@kbn/config-schema';

import {
DEFAULT_MICROSOFT_EXCHANGE_URL,
DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
DEFAULT_MICROSOFT_GRAPH_API_URL,
} from '../../common';
import { ActionTypeRegistry, ActionTypeRegistryOpts } from '../action_type_registry';
import { ActionsClient } from './actions_client';
import { ExecutorType, ActionType } from '../types';
Expand Down Expand Up @@ -596,6 +600,9 @@ describe('create()', () => {
proxyVerificationMode: 'full',
},
enableFooterInEmail: true,
microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL,
microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL,
});

const localActionTypeRegistryParams = {
Expand Down
9 changes: 8 additions & 1 deletion x-pack/plugins/actions/server/actions_config.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
* 2.0.
*/

import {
DEFAULT_MICROSOFT_EXCHANGE_URL,
DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
DEFAULT_MICROSOFT_GRAPH_API_URL,
} from '../common';
import { ActionsConfigurationUtilities } from './actions_config';

const createActionsConfigMock = () => {
Expand All @@ -24,7 +29,9 @@ const createActionsConfigMock = () => {
timeout: 360000,
}),
getCustomHostSettings: jest.fn().mockReturnValue(undefined),
getMicrosoftGraphApiUrl: jest.fn().mockReturnValue(undefined),
getMicrosoftGraphApiUrl: jest.fn().mockReturnValue(DEFAULT_MICROSOFT_GRAPH_API_URL),
getMicrosoftGraphApiScope: jest.fn().mockReturnValue(DEFAULT_MICROSOFT_GRAPH_API_SCOPE),
getMicrosoftExchangeUrl: jest.fn().mockReturnValue(DEFAULT_MICROSOFT_EXCHANGE_URL),
validateEmailAddresses: jest.fn().mockReturnValue(undefined),
getMaxAttempts: jest.fn().mockReturnValue(3),
enableFooterInEmail: jest.fn().mockReturnValue(true),
Expand Down
8 changes: 8 additions & 0 deletions x-pack/plugins/actions/server/actions_config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

import { ByteSizeValue } from '@kbn/config-schema';
import { ActionsConfig } from './config';
import {
DEFAULT_MICROSOFT_EXCHANGE_URL,
DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
DEFAULT_MICROSOFT_GRAPH_API_URL,
} from '../common';
import {
getActionsConfigurationUtilities,
AllowedHosts,
Expand Down Expand Up @@ -34,6 +39,9 @@ const defaultActionsConfig: ActionsConfig = {
verificationMode: 'full',
},
enableFooterInEmail: true,
microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL,
microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL,
};

describe('ensureUriAllowed', () => {
Expand Down
16 changes: 14 additions & 2 deletions x-pack/plugins/actions/server/actions_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ export interface ActionsConfigurationUtilities {
getProxySettings: () => undefined | ProxySettings;
getResponseSettings: () => ResponseSettings;
getCustomHostSettings: (targetUrl: string) => CustomHostSettings | undefined;
getMicrosoftGraphApiUrl: () => undefined | string;
getMicrosoftGraphApiUrl: () => string;
getMicrosoftGraphApiScope: () => string;
getMicrosoftExchangeUrl: () => string;
getMaxAttempts: ({
actionTypeMaxAttempts,
actionTypeId,
Expand Down Expand Up @@ -127,10 +129,18 @@ function getProxySettingsFromConfig(config: ActionsConfig): undefined | ProxySet
};
}

function getMicrosoftGraphApiUrlFromConfig(config: ActionsConfig): undefined | string {
function getMicrosoftGraphApiUrlFromConfig(config: ActionsConfig): string {
return config.microsoftGraphApiUrl;
}

function getMicrosoftGraphApiScopeFromConfig(config: ActionsConfig): string {
return config.microsoftGraphApiScope;
}

function getMicrosoftExchangeUrlFromConfig(config: ActionsConfig): string {
return config.microsoftExchangeUrl;
}

function arrayAsSet<T>(arr: T[] | undefined): Set<T> | undefined {
if (!arr) return;
return new Set(arr);
Expand Down Expand Up @@ -209,6 +219,8 @@ export function getActionsConfigurationUtilities(
},
getCustomHostSettings: (targetUrl: string) => getCustomHostSettings(config, targetUrl),
getMicrosoftGraphApiUrl: () => getMicrosoftGraphApiUrlFromConfig(config),
getMicrosoftGraphApiScope: () => getMicrosoftGraphApiScopeFromConfig(config),
getMicrosoftExchangeUrl: () => getMicrosoftExchangeUrlFromConfig(config),
validateEmailAddresses: (addresses: string[], options: ValidateEmailAddressesOptions) =>
validatedEmailCurried(addresses, options),
getMaxAttempts: ({ actionTypeMaxAttempts, actionTypeId }) => {
Expand Down
13 changes: 11 additions & 2 deletions x-pack/plugins/actions/server/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ describe('config validation', () => {
"maxResponseContentLength": ByteSizeValue {
"valueInBytes": 1048576,
},
"microsoftExchangeUrl": "https://login.microsoftonline.com",
"microsoftGraphApiScope": "https://graph.microsoft.com/.default",
"microsoftGraphApiUrl": "https://graph.microsoft.com/v1.0",
"preconfigured": Object {},
"preconfiguredAlertHistoryEsIndex": false,
"proxyRejectUnauthorizedCertificates": true,
Expand Down Expand Up @@ -65,6 +68,9 @@ describe('config validation', () => {
"maxResponseContentLength": ByteSizeValue {
"valueInBytes": 1048576,
},
"microsoftExchangeUrl": "https://login.microsoftonline.com",
"microsoftGraphApiScope": "https://graph.microsoft.com/.default",
"microsoftGraphApiUrl": "https://graph.microsoft.com/v1.0",
"preconfigured": Object {
"mySlack1": Object {
"actionTypeId": ".slack",
Expand Down Expand Up @@ -147,7 +153,7 @@ describe('config validation', () => {
expect(mockLogger.warn.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"The confgurations xpack.actions.proxyBypassHosts and xpack.actions.proxyOnlyHosts can not be used at the same time. The configuration xpack.actions.proxyOnlyHosts will be ignored.",
"The configurations xpack.actions.proxyBypassHosts and xpack.actions.proxyOnlyHosts can not be used at the same time. The configuration xpack.actions.proxyOnlyHosts will be ignored.",
],
]
`);
Expand All @@ -169,7 +175,7 @@ describe('config validation', () => {
expect(mockLogger.warn.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"The confguration xpack.actions.proxyUrl: bad url is invalid.",
"The configuration xpack.actions.proxyUrl: bad url is invalid.",
],
]
`);
Expand Down Expand Up @@ -207,6 +213,9 @@ describe('config validation', () => {
"maxResponseContentLength": ByteSizeValue {
"valueInBytes": 1048576,
},
"microsoftExchangeUrl": "https://login.microsoftonline.com",
"microsoftGraphApiScope": "https://graph.microsoft.com/.default",
"microsoftGraphApiUrl": "https://graph.microsoft.com/v1.0",
"preconfigured": Object {},
"preconfiguredAlertHistoryEsIndex": false,
"proxyRejectUnauthorizedCertificates": true,
Expand Down
13 changes: 10 additions & 3 deletions x-pack/plugins/actions/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

import { schema, TypeOf } from '@kbn/config-schema';
import { Logger } from '@kbn/core/server';
import {
DEFAULT_MICROSOFT_EXCHANGE_URL,
DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
DEFAULT_MICROSOFT_GRAPH_API_URL,
} from '../common';

export enum AllowedHosts {
Any = '*',
Expand Down Expand Up @@ -120,7 +125,9 @@ export const configSchema = schema.object({
maxResponseContentLength: schema.byteSize({ defaultValue: '1mb' }),
responseTimeout: schema.duration({ defaultValue: '60s' }),
customHostSettings: schema.maybe(schema.arrayOf(customHostSettingsSchema)),
microsoftGraphApiUrl: schema.maybe(schema.string()),
microsoftGraphApiUrl: schema.string({ defaultValue: DEFAULT_MICROSOFT_GRAPH_API_URL }),
microsoftGraphApiScope: schema.string({ defaultValue: DEFAULT_MICROSOFT_GRAPH_API_SCOPE }),
microsoftExchangeUrl: schema.string({ defaultValue: DEFAULT_MICROSOFT_EXCHANGE_URL }),
email: schema.maybe(
schema.object({
domain_allowlist: schema.arrayOf(schema.string()),
Expand Down Expand Up @@ -155,13 +162,13 @@ export function getValidatedConfig(logger: Logger, originalConfig: ActionsConfig
try {
new URL(proxyUrl);
} catch (err) {
logger.warn(`The confguration xpack.actions.proxyUrl: ${proxyUrl} is invalid.`);
logger.warn(`The configuration xpack.actions.proxyUrl: ${proxyUrl} is invalid.`);
}
}

if (proxyBypassHosts && proxyOnlyHosts) {
logger.warn(
'The confgurations xpack.actions.proxyBypassHosts and xpack.actions.proxyOnlyHosts can not be used at the same time. The configuration xpack.actions.proxyOnlyHosts will be ignored.'
'The configurations xpack.actions.proxyBypassHosts and xpack.actions.proxyOnlyHosts can not be used at the same time. The configuration xpack.actions.proxyOnlyHosts will be ignored.'
);
const tmp: Record<string, unknown> = originalConfig;
delete tmp.proxyOnlyHosts;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import { createReadySignal } from '@kbn/event-log-plugin/server/lib/ready_signal
import { ActionsConfig } from '../config';
import { ActionsConfigurationUtilities, getActionsConfigurationUtilities } from '../actions_config';
import { resolveCustomHosts } from '../lib/custom_host_settings';
import {
DEFAULT_MICROSOFT_EXCHANGE_URL,
DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
DEFAULT_MICROSOFT_GRAPH_API_URL,
} from '../../common';

const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>;

Expand Down Expand Up @@ -683,6 +688,9 @@ const BaseActionsConfig: ActionsConfig = {
responseTimeout: momentDuration(1000 * 30),
customHostSettings: undefined,
enableFooterInEmail: true,
microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL,
microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL,
};

function getACUfromConfig(config: Partial<ActionsConfig> = {}): ActionsConfigurationUtilities {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import { createReadySignal } from '@kbn/event-log-plugin/server/lib/ready_signal
import { ActionsConfig } from '../config';
import { ActionsConfigurationUtilities, getActionsConfigurationUtilities } from '../actions_config';
import { resolveCustomHosts } from '../lib/custom_host_settings';
import {
DEFAULT_MICROSOFT_GRAPH_API_URL,
DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
DEFAULT_MICROSOFT_EXCHANGE_URL,
} from '../../common';

const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>;

Expand Down Expand Up @@ -589,6 +594,9 @@ const BaseActionsConfig: ActionsConfig = {
responseTimeout: momentDuration(1000 * 30),
customHostSettings: undefined,
enableFooterInEmail: true,
microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL,
microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL,
};

function getACUfromConfig(config: Partial<ActionsConfig> = {}): ActionsConfigurationUtilities {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import { Logger } from '@kbn/core/server';
import { loggingSystemMock } from '@kbn/core/server/mocks';

import { resolveCustomHosts, getCanonicalCustomHostUrl } from './custom_host_settings';
import {
DEFAULT_MICROSOFT_GRAPH_API_URL,
DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
DEFAULT_MICROSOFT_EXCHANGE_URL,
} from '../../common';

const CA_DIR = '../../../../../../packages/kbn-dev-utils/certs';
const CA_FILE1 = pathResolve(__filename, pathJoin(CA_DIR, 'ca.crt'));
Expand Down Expand Up @@ -74,6 +79,9 @@ describe('custom_host_settings', () => {
maxResponseContentLength: new ByteSizeValue(1000000),
responseTimeout: moment.duration(60000),
enableFooterInEmail: true,
microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL,
microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL,
};

test('ensure it copies over the config parts that it does not touch', () => {
Expand Down
16 changes: 15 additions & 1 deletion x-pack/plugins/actions/server/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ import {
ActionsPluginsStart,
PluginSetupContract,
} from './plugin';
import { AlertHistoryEsIndexConnectorId } from '../common';
import {
AlertHistoryEsIndexConnectorId,
DEFAULT_MICROSOFT_EXCHANGE_URL,
DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
DEFAULT_MICROSOFT_GRAPH_API_URL,
} from '../common';

const executor: ExecutorType<{}, {}, {}, void> = async (options) => {
return { status: 'ok', actionId: options.actionId };
Expand All @@ -51,6 +56,9 @@ function getConfig(overrides = {}) {
maxResponseContentLength: new ByteSizeValue(1000000),
responseTimeout: moment.duration('60s'),
enableFooterInEmail: true,
microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL,
microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL,
...overrides,
};
}
Expand All @@ -73,6 +81,9 @@ describe('Actions Plugin', () => {
maxResponseContentLength: new ByteSizeValue(1000000),
responseTimeout: moment.duration(60000),
enableFooterInEmail: true,
microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL,
microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL,
});
plugin = new ActionsPlugin(context);
coreSetup = coreMock.createSetup();
Expand Down Expand Up @@ -534,6 +545,9 @@ describe('Actions Plugin', () => {
maxResponseContentLength: new ByteSizeValue(1000000),
responseTimeout: moment.duration(60000),
enableFooterInEmail: true,
microsoftGraphApiUrl: DEFAULT_MICROSOFT_GRAPH_API_URL,
microsoftGraphApiScope: DEFAULT_MICROSOFT_GRAPH_API_SCOPE,
microsoftExchangeUrl: DEFAULT_MICROSOFT_EXCHANGE_URL,
});
plugin = new ActionsPlugin(context);
coreSetup = coreMock.createSetup();
Expand Down
Loading

0 comments on commit 0313a19

Please sign in to comment.