Skip to content

Commit b754e12

Browse files
committed
feat(security,serverless): enable UIAM mode by default
1 parent cc0e0d3 commit b754e12

31 files changed

Lines changed: 532 additions & 378 deletions

File tree

src/cli/serve/serve.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,8 @@ export default function (program) {
279279
'Collect more complete stack traces. See src/cli/dev.js for explanation.'
280280
)
281281
.option(
282-
'--uiam',
283-
'Configure Kibana with Universal Identity and Access Management (UIAM) support when running in serverless project mode.'
282+
'--no-uiam',
283+
'Prevents configuring Kibana with Universal Identity and Access Management (UIAM) support when running in serverless project mode.'
284284
);
285285
}
286286

@@ -323,7 +323,7 @@ export default function (program) {
323323
cache: !!opts.cache,
324324
dist: !!opts.dist,
325325
serverless: isServerlessMode,
326-
uiam: isServerlessSamlSupported && !!opts.uiam,
326+
uiam: isServerlessSamlSupported && opts.uiam !== false,
327327
};
328328

329329
// In development mode, the main process uses the @kbn/dev-cli-mode
@@ -442,7 +442,7 @@ function tryConfigureServerlessSamlProvider(rawConfig, opts, extraCliOptions) {
442442
});
443443
}
444444

445-
if (opts.uiam && DEV_UTILS_SUPPORTED) {
445+
if (opts.uiam !== false && DEV_UTILS_SUPPORTED) {
446446
// Ensure the key/cert pair is loaded dynamically to exclude it from the production build.
447447
// eslint-disable-next-line import/no-dynamic-require
448448
const { KBN_CERT_PATH, KBN_KEY_PATH } = require(DEV_UTILS_PATH);

src/cli/serve/serve.test.js

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,22 @@ describe('applyConfigOverrides', () => {
8383
});
8484
});
8585

86-
it('alters config to enable SAML Mock IdP in serverless dev mode', () => {
87-
expect(applyConfigOverrides({}, { dev: true, serverless: true }, {}, {})).toEqual({
86+
it('alters config to enable SAML Mock IdP and UIAM in serverless dev mode', () => {
87+
expect(applyConfigOverrides({}, { dev: true, serverless: true, uiam: true }, {}, {})).toEqual({
8888
elasticsearch: {
8989
hosts: ['https://localhost:9200'],
9090
serviceAccountToken: kibanaDevServiceAccount.token,
9191
ssl: { certificateAuthorities: expect.stringContaining('ca.crt') },
9292
},
93+
mockIdpPlugin: { uiam: { enabled: true } },
9394
plugins: { paths: [] },
9495
xpack: {
96+
cloud: {
97+
id: 'local-dev:ZG9ja2VyLmludGVybmFsOjkyMDAkaG9zdDo5MjAwJGtpYmFuYTo5MjAw',
98+
organization_id: 'org1234567890',
99+
projects_url: '',
100+
serverless: { project_id: 'abcdef12345678901234567890123456' },
101+
},
95102
security: {
96103
authc: {
97104
providers: {
@@ -108,27 +115,30 @@ describe('applyConfigOverrides', () => {
108115
},
109116
selector: { enabled: false },
110117
},
118+
uiam: {
119+
enabled: true,
120+
sharedSecret: 'Dw7eRt5yU2iO9pL3aS4dF6gH8jK0lZ1xC2vB3nM4qW5=',
121+
url: 'https://localhost:8443',
122+
ssl: {
123+
certificate: KBN_CERT_PATH,
124+
key: KBN_KEY_PATH,
125+
verificationMode: 'none',
126+
},
127+
},
111128
},
112129
},
113130
});
114131
});
115132

116-
it('alters config to enable UIAM if `--uiam` flag is passed in serverless dev mode', () => {
117-
expect(applyConfigOverrides({}, { dev: true, serverless: true, uiam: true }, {}, {})).toEqual({
133+
it('omits UIAM config if `--no-uiam` flag is passed in serverless dev mode', () => {
134+
expect(applyConfigOverrides({}, { dev: true, serverless: true, uiam: false }, {}, {})).toEqual({
118135
elasticsearch: {
119136
hosts: ['https://localhost:9200'],
120137
serviceAccountToken: kibanaDevServiceAccount.token,
121138
ssl: { certificateAuthorities: expect.stringContaining('ca.crt') },
122139
},
123-
mockIdpPlugin: { uiam: { enabled: true } },
124140
plugins: { paths: [] },
125141
xpack: {
126-
cloud: {
127-
id: 'local-dev:ZG9ja2VyLmludGVybmFsOjkyMDAkaG9zdDo5MjAwJGtpYmFuYTo5MjAw',
128-
organization_id: 'org1234567890',
129-
projects_url: '',
130-
serverless: { project_id: 'abcdef12345678901234567890123456' },
131-
},
132142
security: {
133143
authc: {
134144
providers: {
@@ -145,16 +155,6 @@ describe('applyConfigOverrides', () => {
145155
},
146156
selector: { enabled: false },
147157
},
148-
uiam: {
149-
enabled: true,
150-
sharedSecret: 'Dw7eRt5yU2iO9pL3aS4dF6gH8jK0lZ1xC2vB3nM4qW5=',
151-
url: 'https://localhost:8443',
152-
ssl: {
153-
certificate: KBN_CERT_PATH,
154-
key: KBN_KEY_PATH,
155-
verificationMode: 'none',
156-
},
157-
},
158158
},
159159
},
160160
});

src/platform/packages/private/kbn-mock-idp-utils/src/utils.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,11 +318,16 @@ export async function createUiamSessionTokens({
318318
const givenName = fullName ? fullName.split(' ')[0] : 'Test';
319319
const familyName = fullName ? fullName.split(' ').slice(1).join(' ') : 'User';
320320

321+
// UIAM expects project types to be in a specific format, so we need to convert the project type
322+
// if it's one of the known types.
323+
const uiamProjectType =
324+
projectType === 'oblt' ? 'observability' : projectType === 'es' ? 'elasticsearch' : projectType;
325+
321326
const userSeedResult = await seedTestUser({
322327
userId: username,
323328
organizationId,
324329
roleId: 'cloud-role-id',
325-
projectType,
330+
projectType: uiamProjectType,
326331
applicationRoles: roles,
327332
email,
328333
firstName: givenName,
@@ -358,7 +363,7 @@ export async function createUiamSessionTokens({
358363
{
359364
role_id: 'cloud-role-id',
360365
organization_id: organizationId,
361-
project_type: projectType,
366+
project_type: uiamProjectType,
362367
application_roles: roles,
363368
project_scope: { scope: 'all' },
364369
},

src/platform/packages/shared/kbn-es/src/cli_commands/serverless.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export const serverless: Command = {
6464
${SERVERLESS_RESOURCES_PATHS.map((filePath) => basename(filePath)).join(
6565
' | '
6666
)}
67-
--uiam Configure ES serverless with Universal Identity and Access Management (UIAM) support.
67+
--uiam Configure ES serverless with Universal Identity and Access Management (UIAM) support [default: true].
6868
6969
-E Additional key=value settings to pass to ES
7070
-F Absolute paths for files to mount into containers
@@ -118,6 +118,7 @@ export const serverless: Command = {
118118
kibanaUrl: 'http://localhost:5601/',
119119
dataPath: 'stateless',
120120
ssl: true,
121+
uiam: true,
121122
},
122123
}) as unknown as ServerlessOptions;
123124

src/platform/packages/shared/kbn-es/src/utils/docker_uiam.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ describe(`#runUiamContainer()`, () => {
190190
"--env",
191191
"quarkus.log.category.\\"co.elastic.cloud.uiam\\".level=DEBUG",
192192
"--env",
193+
"quarkus.log.category.\\"co.elastic.cloud.uiam.app.authentication.ClientCertificateExtractor\\".level=INFO",
194+
"--env",
193195
"quarkus.log.console.json.enabled=false",
194196
"--env",
195197
"quarkus.log.level=INFO",

src/platform/packages/shared/kbn-es/src/utils/docker_uiam.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ export const UIAM_CONTAINERS = [
154154
'--env',
155155
`quarkus.log.category."co.elastic.cloud.uiam".level=${env.UIAM_APP_LOGGING_LEVEL}`,
156156
'--env',
157+
`quarkus.log.category."co.elastic.cloud.uiam.app.authentication.ClientCertificateExtractor".level=${env.UIAM_LOGGING_LEVEL}`,
158+
'--env',
157159
'quarkus.log.console.json.enabled=false',
158160
'--env',
159161
`quarkus.log.level=${env.UIAM_LOGGING_LEVEL}`,

src/platform/packages/shared/kbn-scout/src/servers/configs/config_sets/automatic_import_v2/serverless/security_complete.serverless.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import type { ScoutServerConfig } from '../../../../../types';
1212

1313
export const servers: ScoutServerConfig = {
1414
...defaultConfig,
15-
esServerlessOptions: { uiam: true },
1615
kbnTestServer: {
1716
...defaultConfig.kbnTestServer,
1817
serverArgs: [

src/platform/packages/shared/kbn-scout/src/servers/configs/config_sets/default/serverless/serverless.base.config.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { resolve, join } from 'path';
1111
import { format as formatUrl } from 'url';
1212
import Fs from 'fs';
1313

14-
import { CA_CERT_PATH, kibanaDevServiceAccount } from '@kbn/dev-utils';
14+
import { CA_CERT_PATH, KBN_CERT_PATH, KBN_KEY_PATH, kibanaDevServiceAccount } from '@kbn/dev-utils';
1515
import {
1616
fleetPackageRegistryDockerImage,
1717
defineDockerServersConfig,
@@ -21,6 +21,8 @@ import {
2121
MOCK_IDP_REALM_NAME,
2222
MOCK_IDP_UIAM_ORGANIZATION_ID,
2323
MOCK_IDP_UIAM_PROJECT_ID,
24+
MOCK_IDP_UIAM_SERVICE_URL,
25+
MOCK_IDP_UIAM_SHARED_SECRET,
2426
} from '@kbn/mock-idp-utils';
2527
import { REPO_ROOT } from '@kbn/repo-info';
2628
import type { ScoutServerConfig } from '../../../../../types';
@@ -37,6 +39,9 @@ const dockerArgs: string[] = ['-v', `${packageRegistryConfig}:/package-registry/
3739
*/
3840
const dockerRegistryPort: string | undefined = process.env.FLEET_PACKAGE_REGISTRY_PORT;
3941

42+
// Indicates whether the config is used on CI or locally.
43+
const isRunOnCI = process.env.CI;
44+
4045
const servers = {
4146
elasticsearch: {
4247
protocol: 'https',
@@ -94,6 +99,7 @@ export const defaultConfig: ScoutServerConfig = {
9499
],
95100
ssl: true, // SSL is required for SAML realm
96101
},
102+
esServerlessOptions: { uiam: true },
97103
kbnTestServer: {
98104
buildArgs: [],
99105
env: {
@@ -150,7 +156,14 @@ export const defaultConfig: ScoutServerConfig = {
150156
'--xpack.cloud.base_url=https://fake-cloud.elastic.co',
151157
'--xpack.cloud.billing_url=/billing/overview/',
152158
'--xpack.cloud.deployments_url=/deployments',
153-
'--xpack.cloud.id=ftr_fake_cloud_id',
159+
// cloud.id is decoded by the security plugin to obtain the ES endpoint for UIAM API key conversion.
160+
// CI: decodes to https://es01:9220 (ES listens on port 9220 inside the Docker network)
161+
// Local: decodes to https://host.docker.internal:9220 (ES is on the host, reached via Docker bridge)
162+
`--xpack.cloud.id=${
163+
isRunOnCI
164+
? 'ci:ZXMwMTo5MjIwJDo5MjIwJGtpYmFuYTo5MjIw'
165+
: 'local-dev:ZG9ja2VyLmludGVybmFsOjkyMjAkaG9zdDo5MjIwJGtpYmFuYTo5MjIw'
166+
}`,
154167
`--xpack.cloud.organization_id=${MOCK_IDP_UIAM_ORGANIZATION_ID}`,
155168
'--xpack.cloud.organization_url=/account/',
156169
'--xpack.cloud.profile_url=/user/settings/',
@@ -194,6 +207,13 @@ export const defaultConfig: ScoutServerConfig = {
194207
],
195208
},
196209
])}`,
210+
...(isRunOnCI ? [] : ['--mockIdpPlugin.uiam.enabled=true']),
211+
`--xpack.security.uiam.enabled=true`,
212+
`--xpack.security.uiam.url=${MOCK_IDP_UIAM_SERVICE_URL}`,
213+
`--xpack.security.uiam.sharedSecret=${MOCK_IDP_UIAM_SHARED_SECRET}`,
214+
`--xpack.security.uiam.ssl.certificate=${KBN_CERT_PATH}`,
215+
`--xpack.security.uiam.ssl.key=${KBN_KEY_PATH}`,
216+
'--xpack.security.uiam.ssl.verificationMode=none',
197217
],
198218
},
199219
};

src/platform/packages/shared/kbn-scout/src/servers/configs/config_sets/uiam_local/serverless/observability_complete.serverless.config.ts

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,23 @@
77
* License v3.0 only", or the "Server Side Public License, v 1".
88
*/
99

10-
import { MOCK_IDP_UIAM_SERVICE_URL, MOCK_IDP_UIAM_SHARED_SECRET } from '@kbn/mock-idp-utils';
11-
import { KBN_CERT_PATH, KBN_KEY_PATH } from '@kbn/dev-utils';
12-
import { servers as defaultConfig } from '../../default/serverless/security_complete.serverless.config';
10+
import { resolve } from 'path';
11+
import { REPO_ROOT } from '@kbn/repo-info';
12+
import { servers as defaultConfig } from '../../default/serverless/observability_complete.serverless.config';
1313
import type { ScoutServerConfig } from '../../../../../types';
1414

15-
// Indicates whether the config is used on CI or locally.
16-
const isRunOnCI = process.env.CI;
15+
// We need to test certain APIs that are only exposed by the plugin contract and not through
16+
// any HTTP endpoint, so this test plugin exposes these APIs through test HTTP endpoints that
17+
// we can call in our tests.
18+
const pluginPath = `--plugin-path=${resolve(
19+
REPO_ROOT,
20+
'x-pack/platform/test/security_functional/plugins/test_endpoints'
21+
)}`;
1722

1823
export const servers: ScoutServerConfig = {
1924
...defaultConfig,
20-
esServerlessOptions: { uiam: true },
2125
kbnTestServer: {
2226
...defaultConfig.kbnTestServer,
23-
serverArgs: [
24-
...defaultConfig.kbnTestServer.serverArgs,
25-
...(isRunOnCI ? [] : ['--mockIdpPlugin.uiam.enabled=true']),
26-
`--xpack.security.uiam.enabled=true`,
27-
`--xpack.security.uiam.url=${MOCK_IDP_UIAM_SERVICE_URL}`,
28-
`--xpack.security.uiam.sharedSecret=${MOCK_IDP_UIAM_SHARED_SECRET}`,
29-
`--xpack.security.uiam.ssl.certificate=${KBN_CERT_PATH}`,
30-
`--xpack.security.uiam.ssl.key=${KBN_KEY_PATH}`,
31-
'--xpack.security.uiam.ssl.verificationMode=none',
32-
],
27+
serverArgs: [...defaultConfig.kbnTestServer.serverArgs, pluginPath],
3328
},
3429
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
import { resolve } from 'path';
11+
import { REPO_ROOT } from '@kbn/repo-info';
12+
import { servers as defaultConfig } from '../../default/serverless/observability_logs_essentials.serverless.config';
13+
import type { ScoutServerConfig } from '../../../../../types';
14+
15+
// We need to test certain APIs that are only exposed by the plugin contract and not through
16+
// any HTTP endpoint, so this test plugin exposes these APIs through test HTTP endpoints that
17+
// we can call in our tests.
18+
const pluginPath = `--plugin-path=${resolve(
19+
REPO_ROOT,
20+
'x-pack/platform/test/security_functional/plugins/test_endpoints'
21+
)}`;
22+
23+
export const servers: ScoutServerConfig = {
24+
...defaultConfig,
25+
kbnTestServer: {
26+
...defaultConfig.kbnTestServer,
27+
serverArgs: [...defaultConfig.kbnTestServer.serverArgs, pluginPath],
28+
},
29+
};

0 commit comments

Comments
 (0)